# How to salt PBKDF2, when generating both an AES key and a HMAC key for Encrypt then MAC?

When using Encrypt-then-MAC with AES and HMAC by password, and given 128 bits of payload with the ciphertext to store a random salt, which would be more secure:

• Using PBKDF2 with then entire 128 bit random salt and generating 512 bits of derived data to split into a 256 bit AES Key and a 256 bit HMAC key.

or

• Using PBKDF2 separately for each key using two 64 bits salts to generate a 256 bit AES Key and a 256 bit HMAC key.

or

• Better option?
-

I'd use HKDF's "expand" step to generate multiple keys from one masterkey.

Use PBKDF2 to derive that masterkey from the password and salt. i.e. replace the "extract" step of HKDF with PBKDF2.

//Extract

//Expand
AES-Key = HMAC(MasterKey, "AES-Key" | 0x01)
MAC-Key = HMAC(MasterKey, "MAC-Key" | 0x01)


(where | denotes concatenation)

Having PBKDF2 output more than its native size is a bad idea IMO. It increases the cost for the defender considerably (multiple key derivations with thousands of iterations) but doesn't increase the cost for the attacker(he can verify correctness of his password guess after one key was derived, he doesn't need both).

If you use a 512 bit hash, such as SHA-512 in PBKDF2 (PBKDF2-HMAC-SHA-512) you can also get away with simply splitting those 512 bits into two parts, using one for encryption and the other for MAC. But IMO the HKDF approach is cleaner.

-
What does the concatenation of 0x01 provide us? – d1str0 Mar 7 at 7:58
@d1str0 If you never need more than one block of output, it's pointless. But HKDF supports larger outputs, where the last byte of the message acts as counter (it also includes the previous output in the message, similar to OFB mode). – CodesInChaos Mar 7 at 8:01
So would this be similar to HMAC(MasterKey, 0x01) and HMAC(MasterKey, 0x02)? – d1str0 Mar 7 at 8:08
h1 = HMAC(MasterKey, info | 0x01), h2 = HMAC(MasterKey, h1 | info | 0x02), ... Just look at the HKDF spec I linked above for the details. – CodesInChaos Mar 7 at 8:13
@d1str0 It's not strictly needed for security, but it ensures that each iteration of the hash has a unique input. – CodesInChaos Mar 7 at 8:19