/// <summary> /// 2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption) /// </summary> private static byte[] GenerateEcma376SecretKey(string password, byte[] saltValue, HashIdentifier hashIdentifier, int keySize, int verifierHashSize) { byte[] hash; using (var hashAlgorithm = CryptoHelpers.Create(hashIdentifier)) { hash = hashAlgorithm.ComputeHash(CryptoHelpers.Combine(saltValue, System.Text.Encoding.Unicode.GetBytes(password))); for (int i = 0; i < 50000; i++) { hash = hashAlgorithm.ComputeHash(CryptoHelpers.Combine(BitConverter.GetBytes(i), hash)); } hash = hashAlgorithm.ComputeHash(CryptoHelpers.Combine(hash, BitConverter.GetBytes(0))); // The algorithm in this 'DeriveKey' function is the bit that's not clear from the documentation hash = DeriveKey(hash, hashAlgorithm, keySize, verifierHashSize); } Array.Resize(ref hash, keySize / 8); return(hash); }
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"); } }
private static byte[] GenerateSecretKey(string password, byte[] saltValue, HashIdentifier hashAlgorithm, byte[] encryptedKeyValue, int spinCount, int keyBits, SymmetricAlgorithm cipher) { var block3 = new byte[] { 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 }; var h = HashPassword(password, saltValue, hashAlgorithm, spinCount); h = CryptoHelpers.HashBytes(CryptoHelpers.Combine(h, block3), hashAlgorithm); // Truncate or pad with 0x36 var hashSize = h.Length; Array.Resize(ref h, keyBits / 8); for (var i = hashSize; i < keyBits / 8; i++) { h[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, h, saltValue); Array.Resize(ref decryptedKeyValue, keyBits / 8); return(decryptedKeyValue); }
public override SymmetricAlgorithm CreateCipher() { return(CryptoHelpers.CreateCipher(CipherAlgorithm, KeyBits, BlockSize * 8, CipherChaining)); }
/// <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)); }
public override SymmetricAlgorithm CreateCipher() { return(CryptoHelpers.CreateCipher(CipherAlgorithm, KeySize, BlockSize, CipherMode.ECB)); }
public override byte[] GenerateBlockKey(int blockNumber, byte[] secretKey) { var salt = CryptoHelpers.Combine(secretKey, BitConverter.GetBytes(blockNumber)); return(CryptoHelpers.HashBytes(salt, HashIdentifier.MD5)); }
public override SymmetricAlgorithm CreateCipher() { return(CryptoHelpers.CreateCipher(CipherIdentifier.RC4, 0, 0, 0)); }