Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm deriving keys from a user-supplied passphrase for symmetric encryption using AES-256 in CBC mode with a HMAC for authenticity/integrity.

My key derivation function currently looks like this:

enter image description here

Please note that scrypt could just as easily be subbed out for PBKDF2 or bcrypt, that remains to be seen.

I have a couple questions:

  1. Does input truncation using SHA-256 expose any potential weaknesses?
    • My reasoning for doing it in the first place is because many algorithms like bcrypt only accept a limited password input size. (bcrypt seems to accept up to 55 or 72 characters, not sure on the source of this)
    • Would it be better to prefer a hash method with a longer output, ie SHA-512?
  2. When generating the HMAC authentication and encryption keys, would I benefit at all from using SHA-512?
    • AES-256 IIRC needs 256-bit keys, so if I either used AES-192 or used SHA-512, how would I go about fixing the discrepancy in required size?
share|improve this question
You might want to replace the last step by HKDF-Expand. – CodesInChaos Nov 23 '15 at 10:40

Does input truncation using SHA-256 expose any potential weaknesses?

No, hashing the passphrase with SHA-256 will be no stronger or weaker than feeding it in directly. If you go with Scrypt (which I would recommend you do), there are no restrictions on the size of the passphrase... and Scrypt consumes it internally with one round of PBKDF2-HMAC-SHA256 anyway.

When generating the HMAC authentication and encryption keys, would I benefit at all from using SHA-512?

No, you wouldn't. In fact, this step is unnecessary. Just use the output of Scrypt directly... randomBytes = Scrypt(passphrase); encKey = randomBytes[0, 31]; authKey = randomBytes[32, 63]

share|improve this answer
" Just use the output of Scrypt " only applies if it is outputting 512 bits of data – Richie Frame May 23 '14 at 19:05
@RichieFrame - of course... it's simply a matter of requesting 512 bits of output. – hunter May 23 '14 at 19:27
Scrypt uses SHA256 as part of its output function, one could replace that with SHA512 to natively output 512 bits instead of using PBKDF2-SHA256 looped – Richie Frame May 23 '14 at 19:54
@hunter, scrypt calls PBKDF2 with a large output size, meaning multiple SHA256-HMAC invocations are done in parallel with the password and differing block numbers. Wouldn't this mean that scrypt can theoretically use more of the password than the 256 bits that SHA-256 preprocessing would truncate it to? Edit: Of course, if you only use 256 bits of the output (like the OP), that's moot... – otus May 23 '14 at 20:08
Although the bits are independent, I think there is something to be said about using a separate KDF to retrieve the separate keys. I think that is actually more elegant and clear than simply using following output. It is also less error prone; if you would replace scrypt by PBKDF2, you would for instance get in trouble. I would however go for a well defined KBKDF such as HKDF instead of inventing your own. – Maarten Bodewes May 27 '14 at 0:00

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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