Esempio n. 1
0
        public override bool VerifyPassword(string password)
        {
            var secretKey = HashPassword(password, PasswordSaltValue, PasswordHashAlgorithm, PasswordSpinCount);

            var inputBlockKey = CryptoHelpers.HashBytes(
                CryptoHelpers.Combine(secretKey, new byte[] { 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79 }),
                PasswordHashAlgorithm);

            Array.Resize(ref inputBlockKey, PasswordKeyBits / 8);

            var valueBlockKey = CryptoHelpers.HashBytes(
                CryptoHelpers.Combine(secretKey, new byte[] { 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e }),
                PasswordHashAlgorithm);

            Array.Resize(ref valueBlockKey, PasswordKeyBits / 8);

            using (var cipher = CryptoHelpers.CreateCipher(PasswordCipherAlgorithm, PasswordKeyBits, PasswordBlockSize * 8, PasswordCipherChaining))
            {
                var decryptedVerifier     = CryptoHelpers.DecryptBytes(cipher, PasswordEncryptedVerifierHashInput, inputBlockKey, PasswordSaltValue);
                var decryptedVerifierHash = CryptoHelpers.DecryptBytes(cipher, PasswordEncryptedVerifierHashValue, valueBlockKey, PasswordSaltValue);

                var verifierHash = CryptoHelpers.HashBytes(decryptedVerifier, PasswordHashAlgorithm);
                for (var i = 0; i < Math.Min(decryptedVerifierHash.Length, verifierHash.Length); ++i)
                {
                    if (decryptedVerifierHash[i] != verifierHash[i])
                    {
                        return(false);
                    }
                }

                return(true);
            }
        }
Esempio n. 2
0
        private static byte[] DeriveKey(byte[] hashValue, HashAlgorithm hashAlgorithm, int keySize, int verifierHashSize)
        {
            // And one more hash to derive the key
            byte[] derivedKey = new byte[64];

            // This is step 4a in 2.3.4.7 of MS_OFFCRYPT version 1.0
            // and is required even though the notes say it should be
            // used only when the encryption algorithm key > hash length.
            for (int i = 0; i < derivedKey.Length; i++)
            {
                derivedKey[i] = (byte)(i < hashValue.Length ? 0x36 ^ hashValue[i] : 0x36);
            }

            byte[] x1 = hashAlgorithm.ComputeHash(derivedKey);

            if (verifierHashSize > keySize / 8)
            {
                return(x1);
            }

            for (int i = 0; i < derivedKey.Length; i++)
            {
                derivedKey[i] = (byte)(i < hashValue.Length ? 0x5C ^ hashValue[i] : 0x5C);
            }

            byte[] x2 = hashAlgorithm.ComputeHash(derivedKey);
            return(CryptoHelpers.Combine(x1, x2));
        }
Esempio n. 3
0
        public override byte[] GenerateBlockKey(int blockNumber, byte[] secretKey)
        {
            var salt = CryptoHelpers.HashBytes(CryptoHelpers.Combine(secretKey, BitConverter.GetBytes(blockNumber)), HashAlgorithm);

            Array.Resize(ref salt, BlockSize);
            return(salt);
        }
Esempio n. 4
0
        private static byte[] GenerateSecretKey(string password, byte[] saltValue, HashIdentifier hashIdentifier, byte[] encryptedKeyValue, int spinCount, int keyBits, SymmetricAlgorithm cipher)
        {
            var block3 = new byte[] { 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 };

            byte[] hash;
            using (var hashAlgorithm = CryptoHelpers.Create(hashIdentifier))
            {
                hash = HashPassword(password, saltValue, hashAlgorithm, spinCount);

                hash = CryptoHelpers.HashBytes(CryptoHelpers.Combine(hash, block3), hashIdentifier);
            }

            // Truncate or pad with 0x36
            var hashSize = hash.Length;

            Array.Resize(ref hash, keyBits / 8);
            for (var i = hashSize; i < keyBits / 8; i++)
            {
                hash[i] = 0x36;
            }

            // NOTE: the stored salt is padded to a multiple of the block size which affects AES-192
            var decryptedKeyValue = CryptoHelpers.DecryptBytes(cipher, encryptedKeyValue, hash, saltValue);

            Array.Resize(ref decryptedKeyValue, keyBits / 8);
            return(decryptedKeyValue);
        }
Esempio n. 5
0
        private static byte[] HashPassword(string password, byte[] saltValue, HashIdentifier hashAlgorithm, int spinCount)
        {
            var h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(saltValue, System.Text.Encoding.Unicode.GetBytes(password)), hashAlgorithm);

            for (var i = 0; i < spinCount; i++)
            {
                h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(BitConverter.GetBytes(i), h), hashAlgorithm);
            }

            return(h);
        }
Esempio n. 6
0
        public static byte[] GenerateSecretKey(string password, byte[] salt)
        {
            if (password.Length > 16)
            {
                password = password.Substring(0, 16);
            }
            var h = CryptoHelpers.HashBytes(System.Text.Encoding.Unicode.GetBytes(password), HashIdentifier.MD5);

            Array.Resize(ref h, 5);

            // Combine h + salt 16 times:
            h = CryptoHelpers.Combine(h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt, h, salt);
            h = CryptoHelpers.HashBytes(h, HashIdentifier.MD5);
            Array.Resize(ref h, 5);
            return(h);
        }
Esempio n. 7
0
        internal static ushort CreatePasswordVerifier_Method1(byte[] passwordBytes)
        {
            var    passwordArray = CryptoHelpers.Combine(new byte[] { (byte)passwordBytes.Length }, passwordBytes);
            ushort verifier      = 0x0000;

            for (var i = 0; i < passwordArray.Length; ++i)
            {
                var    passwordByte  = passwordArray[passwordArray.Length - 1 - i];
                ushort intermediate1 = (ushort)(((verifier & 0x4000) == 0) ? 0 : 1);
                ushort intermediate2 = (ushort)(verifier * 2);
                intermediate2 &= 0x7FFF;
                ushort intermediate3 = (ushort)(intermediate1 | intermediate2);
                verifier = (ushort)(intermediate3 ^ passwordByte);
            }

            return((ushort)(verifier ^ 0xCE4B));
        }
        /// <summary>
        /// 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)
        /// </summary>
        private static byte[] GenerateEcma376SecretKey(string password, byte[] saltValue, HashIdentifier hashAlgorithm, int keySize, int verifierHashSize)
        {
            var h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(saltValue, System.Text.Encoding.Unicode.GetBytes(password)), hashAlgorithm);

            for (int i = 0; i < 50000; i++)
            {
                h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(BitConverter.GetBytes(i), h), hashAlgorithm);
            }

            h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(h, BitConverter.GetBytes(0)), hashAlgorithm);

            // The algorithm in this 'DeriveKey' function is the bit that's not clear from the documentation
            h = DeriveKey(h, hashAlgorithm, keySize, verifierHashSize);

            Array.Resize(ref h, keySize / 8);

            return(h);
        }
Esempio n. 9
0
 public override byte[] GenerateBlockKey(int blockNumber, byte[] secretKey)
 {
     if ((Flags & EncryptionHeaderFlags.AES) != 0)
     {
         /*var salt = CryptoHelpers.Combine(secretKey, BitConverter.GetBytes(blockNumber));
          * salt = CryptoHelpers.HashBytes(salt, HashAlgorithm);
          * Array.Resize(ref salt, (int)KeySize / 8);
          * return salt;*/
         throw new Exception("Block key for ECMA-376 Standard Encryption not implemented");
     }
     else if ((Flags & EncryptionHeaderFlags.CryptoAPI) != 0)
     {
         var salt = CryptoHelpers.Combine(secretKey, BitConverter.GetBytes(blockNumber));
         salt = CryptoHelpers.HashBytes(salt, HashAlgorithm);
         Array.Resize(ref salt, (int)KeySize / 8);
         return(salt);
     }
     else
     {
         throw new InvalidOperationException("Unknown encryption type");
     }
 }
Esempio n. 10
0
 /// <summary>
 /// 2.3.5.2 RC4 CryptoAPI Encryption Key Generation
 /// </summary>
 private static byte[] GenerateCryptoApiSecretKey(string password, byte[] saltValue, HashIdentifier hashAlgorithm, int keySize)
 {
     return(CryptoHelpers.HashBytes(CryptoHelpers.Combine(saltValue, System.Text.Encoding.Unicode.GetBytes(password)), hashAlgorithm));
 }
Esempio n. 11
0
        public override byte[] GenerateBlockKey(int blockNumber, byte[] secretKey)
        {
            var salt = CryptoHelpers.Combine(secretKey, BitConverter.GetBytes(blockNumber));

            return(CryptoHelpers.HashBytes(salt, HashIdentifier.MD5));
        }