Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

This question already has an answer here:

I'm encrypting a file with AES-256 in CBC mode. I needed to add an HMAC for authentication and validation of the file contents and passphrase, so I used a SHA-256 HMAC over chunks of my file cumulatively.

My main question is how to derive both an HMAC key and my AES key from an input passphrase. I'm currently taking the SHA-512 hash of the input passphrase, passing that to bcrypt/PBKDF2 with a salt and high rounds, and then using the SHA-256 hash to supply my AES cipher password. For deriving an HMAC key in addition to my cipher key, I was thinking of doing one of the following things:

  1. SHA-512 the output from the strong hash method and split the result in half, using the first half as the cipher passphrase and the second half as the HMAC passphrase.
  2. Store an additional salt in my header, and after generating the passphrase using SHA-256 after the strong hash, run the result through SHA-256 again with the salt for the HMAC passphrase.
  3. Same as #2, but without a salt.

Which of these ways is the best way to generate a HMAC password in addition to my cipher password from the same input passphrase?

share|improve this question

marked as duplicate by Ilmari Karonen, mikeazo Feb 27 '13 at 12:34

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

add comment

2 Answers 2

If you are doing authenticated encryption with an AES and HMAC combination, the security of your scheme depends on the key for encryption and the key for message authentication being independent. The general idea is that you might generate two independent keys from a single master key, by proper usage of a $PRF$. The most performance effective solution is therefore to modify your first suggestion in either of two ways:

Let $K$ be the output from the PBKDF2.

  • Alt 1. Derive the encryption key $K_e$ and authentication key $K_a$ using one call each to $K_n = PRF_K(label_n)$. The input $label_n$ might e.g. be the single char "e" and "a" respectively.
  • Alt 2. Derive $K' = K_e||K_a$ using a single call to $PRF_K$ to generate a 512 bit derived key.

Please note SHA-512 is not a pseudo random function, but might be used to create one. For instance, you could use HMAC-SHA-512 as your PRF.

share|improve this answer
    
I don't know of any pseudo-random functions. I'm therefore not sure what you're suggesting. Should I use a PRF to generate two salts, then with the two different salts, generate an encryption key and authentication key? (Eg: where $r$ is the output from os.urandom(32) [32 bytes of pseudo-random data], derive the keys like $k\_{n} = sha256(k + r)$?) –  Naftuli Tzvi Kay Feb 26 '13 at 19:23
    
HMAC-SHA-512 is a PRF, as stated in the answer. –  Henrick Hellström Feb 26 '13 at 19:45
    
So, essentially: hmac.new(master_key, "a", hashlib.sha512).digest() for the HMAC authentication key? Since I need a 256-bit key, would SHA-256 also work? –  Naftuli Tzvi Kay Feb 26 '13 at 19:51
    
Yes, that should work. (I am not familiar with the framework you are using in your example, but it looks right.) –  Henrick Hellström Feb 26 '13 at 19:54
    
I guess my main problem was in understanding how HMAC(input, salt) is different from HASH(input + salt), but if it works, it works :) –  Naftuli Tzvi Kay Feb 26 '13 at 20:02
show 3 more comments

It greatly depends on whether or not your system is closed or opened, how many users you will have, what kind, how and where the software will be run, etc.

As a general rule, you should store only true random data in your cyphertexts (rather than hashes). Your solution #2 is the closest to that goal.

Just keep in mind that as SHA has been designed for speed, it might be a two-sided sword, allowing opponents to brute-force things easier (or worse, if they are competent).

In this regard, if security is really a concern, you should build your own variable-based hashing method (be very creative - the least conventional the best it will be) to make sure that the hashing method is changing with the input data.

Then, test it for collisions to make sure you are not defeating the purpose of using hashing in the first place.

share|improve this answer
3  
Never roll your own crypto. –  Michael Feb 25 '13 at 21:56
1  
...unless you are competent - which obviously is not Michael's case. The same brain-damaged argument was used for G-WAN ("never write your own server"), and G-WAN proved to know better than others. It is striking to see how much academia wants people to be blind "users" rather than actors... –  Gil Feb 26 '13 at 15:53
    
Lol, was this post a joke? Roll your own crypto? Rely on the fact that your system is "closed-source" to ensure security? Everything about this is wrong. –  Naftuli Tzvi Kay Feb 26 '13 at 19:10
    
Vulnerabilites are found in binaries (rather than in source code) - yet another proof of the poor level of skills required to generate those idiotic arguments. –  Gil Feb 27 '13 at 7:17
    
Sorry, but your answer here also doesn't look like you are competent enough to roll your own crypto. I don't think anyone is, short of a big agency with an own staff of some dozens of cryptographers to review your algorithms. –  Paŭlo Ebermann Feb 27 '13 at 21:19
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.