2
votes

Consider a file that will be encrypted by a C# library that I will write, consisting of a 64 byte HMAC followed immediately by the encrypted data encrypted with AES 256. The 16-byte IV, 32-byte Key and 64-byte HMACSHA512 initialisation key will come from Rfc2898DeriveBytes via a single string password, entered by the user (4096 iterations, and a single salt from random.org).

  1. Are there any negative security implications of this design?

  2. Have I gone overboard? (it, with the 64-byte initialisation key or 4096 iterations)

  3. I want to be able to decrypt any data whatsoever in order to use the embedded HMAC to verify that the password was correct (that is, that the 'decrypted file is the original file'). Specifically, I'm looking to avoid errors such as "Padding is invalid and cannot be removed.". Any ideas on how to go about this?

1
1. You must use a different salt each time you encrypt the data with the same key/IV, otherwise security is broken. 2. You may want to have a look at AEAD ciphers.dtb
@dtb It's alright to use the same salt for key derivation from the password; deriving the IV from the password is a problem.erickson
Right, I confused the salt with the nonce/IV. Choosing a different salt should lead to a different IV though.dtb
Just to clarify: The entered password, the fixed salt, and the 4096 iterations will be supplied to Rfc2898DeriveBytes to generate the byte array data for the HMAC initialisation key, as well as the encryption algorithm's Key and IV.Nicholas Hill
To complete my answer, I need to know what the HMAC value is for. It's unclear to me if it is used to check if the password supplied is correct, or if it is used to check if the plain text or cipher text is correct.Maarten Bodewes

1 Answers

1
votes
  1. Yes, the IV should be prepended to the cipher text and should be random. If you use Rfc2898DeriveBytes you will get the same IV each time, so encrypting different plain texts will result in identical cipher texts, leaking information.

  2. Yes, the 64 byte initialization key is a bit much. 16 to 32 bytes should be more than enough. That said, it does not make much difference regarding performance, so... 4Ki iterations is fine (why not just 4000, the algorithm does not change).

  3. Yes, place the HMAC over the encrypted data, and make sure you verify the HMAC before you decrypt (the last block). Normally the HMAC is placed after the cipher text (as a streaming implementation will only know the HMAC once it encrypted all the cipher text).

Alternatively you could use AES in GCM mode so you don't need the HMAC anymore. GCM (or EAX) mode is not always available though.