コード例 #1
0
        /// <summary>
        /// Create an EncryptionInfo object to encrypt a workbook
        /// </summary>
        /// <param name="password">The password</param>
        /// <param name="algID"></param>
        /// <param name="key">The Encryption key</param>
        /// <returns></returns>
        private EncryptionInfoBinary CreateEncryptionInfo(string password, AlgorithmID algID, out byte[] key)
        {
            if (algID == AlgorithmID.Flags || algID == AlgorithmID.RC4)
            {
                throw (new ArgumentException("algID must be AES128, AES192 or AES256"));
            }
            var encryptionInfo = new EncryptionInfoBinary();

            encryptionInfo.MajorVersion = 4;
            encryptionInfo.MinorVersion = 2;
            encryptionInfo.Flags        = Flags.fAES | Flags.fCryptoAPI;

            //Header
            encryptionInfo.Header           = new EncryptionHeader();
            encryptionInfo.Header.AlgID     = algID;
            encryptionInfo.Header.AlgIDHash = AlgorithmHashID.SHA1;
            encryptionInfo.Header.Flags     = encryptionInfo.Flags;
            encryptionInfo.Header.KeySize   =
                (algID == AlgorithmID.AES128 ? 0x80 : algID == AlgorithmID.AES192 ? 0xC0 : 0x100);
            encryptionInfo.Header.ProviderType = ProviderType.AES;
            encryptionInfo.Header.CSPName      = "Microsoft Enhanced RSA and AES Cryptographic Provider\0";
            encryptionInfo.Header.Reserved1    = 0;
            encryptionInfo.Header.Reserved2    = 0;
            encryptionInfo.Header.SizeExtra    = 0;

            //Verifier
            encryptionInfo.Verifier      = new EncryptionVerifier();
            encryptionInfo.Verifier.Salt = new byte[16];

            var rnd = RandomNumberGenerator.Create();

            rnd.GetBytes(encryptionInfo.Verifier.Salt);
            encryptionInfo.Verifier.SaltSize = 0x10;

            key = GetPasswordHashBinary(password, encryptionInfo);

            var verifier = new byte[16];

            rnd.GetBytes(verifier);
            encryptionInfo.Verifier.EncryptedVerifier = EncryptData(key, verifier, true);

            //AES = 32 Bits
            encryptionInfo.Verifier.VerifierHashSize = 0x20;
            var sha =
#if COREFX
                SHA1.Create();
#else
                new SHA1Managed();
#endif
            var verifierHash = sha.ComputeHash(verifier);

            encryptionInfo.Verifier.EncryptedVerifierHash = EncryptData(key, verifierHash, false);

            return(encryptionInfo);
        }
コード例 #2
0
        internal static bool VerifySignature(SafeCspHandle cspHandle,
                                             SafeCspKeyHandle keyHandle,
                                             AlgorithmID signatureAlgorithm,
                                             AlgorithmID hashAlgorithm,
                                             byte[] hashValue,
                                             byte[] signature)
        {
            Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid");
            Contract.Assert(keyHandle != null && !keyHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid");
            Contract.Assert(((AlgorithmClass)signatureAlgorithm & AlgorithmClass.Signature) == AlgorithmClass.Signature, "Invalid signature algorithm");
            Contract.Assert(((AlgorithmClass)hashAlgorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm");
            Contract.Assert(hashValue != null, "hashValue != null");
            Contract.Assert(signature != null, "signature != null");

            // CAPI and the CLR have inverse byte orders for signatures, so we need to reverse before verifying
            byte[] signatureValue = new byte[signature.Length];
            Array.Copy(signature, signatureValue, signatureValue.Length);
            Array.Reverse(signatureValue);

            using (SafeCspHashHandle hashHandle = CreateHashAlgorithm(cspHandle, hashAlgorithm)) {
                // Make sure the hash value is the correct size and import it into the CSP
                if (hashValue.Length != GetHashPropertyInt32(hashHandle, HashProperty.HashSize))
                {
                    throw new CryptographicException((int)ErrorCode.BadHash);
                }
                SetHashProperty(hashHandle, HashProperty.HashValue, hashValue);

                // Do the signature verification.  A TRUE result means that the signature was valid.  A FALSE
                // result either means an invalid signature or some other error, so we need to check the last
                // error to see which occured.
                if (UnsafeNativeMethods.CryptVerifySignature(hashHandle,
                                                             signatureValue,
                                                             signatureValue.Length,
                                                             keyHandle,
                                                             null,
                                                             0))
                {
                    return(true);
                }
                else
                {
                    int error = Marshal.GetLastWin32Error();

                    if (error != (int)ErrorCode.BadSignature)
                    {
                        throw new CryptographicException(error);
                    }

                    return(false);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Create an EncryptionInfo object to encrypt a workbook
        /// </summary>
        /// <param name="password">The password</param>
        /// <param name="algID"></param>
        /// <param name="key">The Encryption key</param>
        /// <returns></returns>
        private EncryptionInfo CreateEncryptionInfo(string password, AlgorithmID algID, out byte[] key)
        {
            if (algID == AlgorithmID.Flags || algID == AlgorithmID.RC4)
            {
                throw(new ArgumentException("algID must be AES128, AES192 or AES256"));
            }
            var encryptionInfo = new EncryptionInfo();
            encryptionInfo.MajorVersion = 4;
            encryptionInfo.MinorVersion = 2;
            encryptionInfo.Flags = Flags.fAES | Flags.fCryptoAPI;

            //Header
            encryptionInfo.Header = new EncryptionHeader();
            encryptionInfo.Header.AlgID = algID;
            encryptionInfo.Header.AlgIDHash = AlgorithmHashID.SHA1;
            encryptionInfo.Header.Flags = encryptionInfo.Flags;
            encryptionInfo.Header.KeySize =
                (algID == AlgorithmID.AES128 ? 0x80 : algID == AlgorithmID.AES192 ? 0xC0 : 0x100);
            encryptionInfo.Header.ProviderType = ProviderType.AES;
            encryptionInfo.Header.CSPName = "Microsoft Enhanced RSA and AES Cryptographic Provider\0";
            encryptionInfo.Header.Reserved1 = 0;
            encryptionInfo.Header.Reserved2 = 0;
            encryptionInfo.Header.SizeExtra = 0;

            //Verifier
            encryptionInfo.Verifier = new EncryptionVerifier();
            encryptionInfo.Verifier.Salt = new byte[16];

            var rnd = RandomNumberGenerator.Create();
            rnd.GetBytes(encryptionInfo.Verifier.Salt);
            encryptionInfo.Verifier.SaltSize = 0x10;

            key = GetPasswordHash(password, encryptionInfo);

            var verifier = new byte[16];
            rnd.GetBytes(verifier);
            encryptionInfo.Verifier.EncryptedVerifier = EncryptData(key, verifier,true);

            //AES = 32 Bits
            encryptionInfo.Verifier.VerifierHashSize = 0x20;
            SHA1 sha= new SHA1Managed();
            var verifierHash = sha.ComputeHash(verifier);

            encryptionInfo.Verifier.EncryptedVerifierHash = EncryptData(key, verifierHash, false);

            return encryptionInfo;
        }
コード例 #4
0
        internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm)
        {
            Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid");
            Contract.Assert(((AlgorithmClass)algorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm");

            SafeCspHashHandle hashHandle = null;

            if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out hashHandle))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return(hashHandle);
        }
コード例 #5
0
 internal static extern bool CryptCreateHash(SafeCspHandle hProv,
                                             AlgorithmID Algid,
                                             IntPtr hKey,                        // SafeCspKeyHandle
                                             int dwFlags,
                                             [Out] out SafeCspHashHandle phHash);
コード例 #6
0
        internal static bool VerifySignature(SafeCspHandle cspHandle,
                                             SafeCspKeyHandle keyHandle,
                                             AlgorithmID signatureAlgorithm,
                                             AlgorithmID hashAlgorithm,
                                             byte[] hashValue,
                                             byte[] signature) {
            Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid");
            Contract.Assert(keyHandle != null && !keyHandle.IsInvalid, "keyHandle != null && !keyHandle.IsInvalid");
            Contract.Assert(((AlgorithmClass)signatureAlgorithm & AlgorithmClass.Signature) == AlgorithmClass.Signature, "Invalid signature algorithm");
            Contract.Assert(((AlgorithmClass)hashAlgorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm");
            Contract.Assert(hashValue != null, "hashValue != null");
            Contract.Assert(signature != null, "signature != null");

            // CAPI and the CLR have inverse byte orders for signatures, so we need to reverse before verifying
            byte[] signatureValue = new byte[signature.Length];
            Array.Copy(signature, signatureValue, signatureValue.Length);
            Array.Reverse(signatureValue);

            using (SafeCspHashHandle hashHandle = CreateHashAlgorithm(cspHandle, hashAlgorithm)) {
                // Make sure the hash value is the correct size and import it into the CSP
                if (hashValue.Length != GetHashPropertyInt32(hashHandle, HashProperty.HashSize)) {
                    throw new CryptographicException((int)ErrorCode.BadHash);
                }
                SetHashProperty(hashHandle, HashProperty.HashValue, hashValue);

                // Do the signature verification.  A TRUE result means that the signature was valid.  A FALSE
                // result either means an invalid signature or some other error, so we need to check the last
                // error to see which occured.
                if (UnsafeNativeMethods.CryptVerifySignature(hashHandle,
                                                                signatureValue,
                                                                signatureValue.Length,
                                                                keyHandle,
                                                                null,
                                                                0)) {
                    return true;
                }
                else {
                    int error = Marshal.GetLastWin32Error();

                    if (error != (int)ErrorCode.BadSignature) {
                        throw new CryptographicException(error);
                    }

                    return false;
                }
            }
        }
コード例 #7
0
        internal static SafeCspHashHandle CreateHashAlgorithm(SafeCspHandle cspHandle, AlgorithmID algorithm) {
            Contract.Assert(cspHandle != null && !cspHandle.IsInvalid, "cspHandle != null && !cspHandle.IsInvalid");
            Contract.Assert(((AlgorithmClass)algorithm & AlgorithmClass.Hash) == AlgorithmClass.Hash, "Invalid hash algorithm");

            SafeCspHashHandle hashHandle = null;
            if (!UnsafeNativeMethods.CryptCreateHash(cspHandle, algorithm, IntPtr.Zero, 0, out hashHandle)) {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return hashHandle;
        }
コード例 #8
0
 internal static extern bool CryptCreateHash(SafeCspHandle hProv,
                                             AlgorithmID Algid,
                                             IntPtr hKey,                        // SafeCspKeyHandle
                                             int dwFlags,
                                             [Out] out SafeCspHashHandle phHash);