问题
I want to include iv
and salt
in the HMACSHA512 calculation without add then to the encrypted data.
At the moment someone could change the iv
and a wouldn't noticed that.
I chain different streams to ensure Encrypt-then-MAC, later I want to encrypt large files, so this design is necessary.
So if I add the the iv
and salt
to a stream, with e.g. new MemoryStream(iv).CopyTo(hmacStream);
the result will contain this data.
This is my code so far:
private static IHmacAndData EncryptInternal(byte[] key, byte[] iv, byte[] plainData, byte[] salt)
{
byte[] hmacHash;
byte[] encryptedBytes;
using (var aesManaged = CreateAesManaged(iv, key))
{
var encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV);
var hmacsha512 = new HMACSHA512(key);
using (var resultStream = new MemoryStream())
{
using (var hmacStream = new CryptoStream(resultStream, hmacsha512, CryptoStreamMode.Write))
{
using (var aesStream = new CryptoStream(hmacStream, encryptor, CryptoStreamMode.Write))
{
using (var plainStream = new MemoryStream(plainData))
{
plainStream.CopyTo(aesStream);
}
}
}
encryptedBytes = resultStream.ToArray();
}
hmacHash = hmacsha512.Hash;
}
return new Message {HMAC = hmacHash, Data = encryptedBytes};
}
private static AesManaged CreateAesManaged(byte[] iv, byte[] key)
{
var aesManaged = new AesManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
KeySize = KeySize,
IV = iv,
Key = key
};
return aesManaged;
}
My temporary solution is to make a second HMACSHA512 calculation at the end. But this seems not right in any way.
var overallHmac = new HMACSHA512(keyHmac);
hmacHash = overallHmac.ComputeHash(hmacHash.Concat(iv).Concat(saltPassword).Concat(saltHmac).ToArray());
Here is the full sample, search for CreateOverallHmacKey
to find the spot.
https://gist.github.com/dhcgn/85b88b516953e8996af8544ee9d7b567
来源:https://stackoverflow.com/questions/39637026/encrypt-then-mac-how-to-afterwards-add-data-to-hmac