# Deriving AES key and HMAC key from shorter master key

I am working in .NET and as far as I can tell the only choice for key derivation is PBKDF2-HMAC-SHA1. SHA1's output size is only 160 bits. But I am implementing authenticated encryption and thus need 512 bits of key material (a 256-bit AES key and a 256-bit HMAC key). My original idea was to input the password, salt, and a high numberOfIterations into PBKDF2 to derive both the AES key and the HMAC key.

Several people pointed out that I was making an attacker's job easier. Getting 512 bits of key material from PBKDF2-HMAC-SHA1 would require ceil(512/160) = 4 calls * numberOfIterations. However, an attacker would only need the AES key to decrypt the message, so he/she would only need to perform ceil(256/160) = 2 calls * numberOfIterations.

I've read two suggestions on how to fix this:

1. Use PBKDF2-HMAC-SHA512. It would provide enough output for both keys. Unfortunatley, .NET doesn't seem to support this.
2. Use PBKDF2-HMAC-SHA1 with the password, salt, and a high numberOfIterations to output a 160-bit master key. Then use HKDF-Expand to expand the master key into two 256-bit keys. Unfortunately .NET doesn't provide HKDF-Expand as far as I can tell.

I have read in other stack exchange posts such as this post and this post that one could derive two keys from a master key (MK) by doing the following:

1. Create 160-bit MK through PBKDF2-HMAC-SHA1 using a user-supplied password, a 160-bit salt, and a high numberOfIterations.
2. Calculate HMAC-SHA256(MK,"e") -> aesKey
3. Calculate HMAC-SHA256(MK,"a") -> hmacKey

Would these steps result in a suitable pair of keys for AES-encrypt-then-HMAC-authenticate?

• Note 1: I realize that the 256-bit aesKey and 256-bit hmacKey would each only have 160 bits of entropy, but that doesn't seem concerning, as the likely attack path would be on the password, not the keys.
• Note 2: Even though .NET does offer HMAC-SHA256, HMAC-SHA512, etc., it does not offer a choice for PBKDF2-HMAC other than PBKDF2-HMAC-SHA1.
• The standard PBKDF2 interface allows you to specify the length of output you want (which need not be limited to the length of the hash function it uses internally). Doesn't .NET implement that parameter? – poncho Apr 20 '16 at 2:35
• If you are worried that an attacker might gain a factor of two advantage by only deriving the AES-256 half, then why don't you ask for 512 bits, and use the even bytes for the AES-256 key and the odd bytes for the HMAC key. That way, he'll need to derive both to test either the decryption or the HMAC. – poncho Apr 20 '16 at 2:42
• Yes, you can get as much output as you want from PBKDF2-HMAC-SHA1. The issue pointed out by others is that for a given number of iterations it will take twice as long to derive the AES key and the HMAC key together than it will take to derive just the AES key. The function has to increase its workload to give more than 160 bits. If 0-160 bits takes n seconds, then 161-320 bits takes 2n seconds, 321-480 bytes takes 3n seconds, etc. So if I use it to get 512 bytes of data then I am running it twice as much as an attacker would who only needs 256 bits of data to try decrypting the ciphertext. – Ralph P Apr 20 '16 at 2:46
• So, did you read my suggestion for using alternative bytes for the two different keys? – poncho Apr 20 '16 at 3:12
• Use .NET bindings to libsodium instead – Demi Apr 20 '16 at 4:40