4

From this question, the OP posited taking a user's entered password, running it through BCrypt, then running that through SHA256 to produce a 256-bit password-derived key. (EDIT: To clarify, these two options are considered as producing a single key value; the "intermediate" BCrypt hash's sole purpose is to be hashed with SHA-256 and is not used for any other purpose). The obvious alternative is to simply plug HMAC-SHA256 in as the PRNG for the PBKDF2 algorithm shell, with an equivalent number of rounds of derivation.

The question is, what are the relative strengths and weaknesses here? Obviously, both approaches, properly implemented and configured, would present a significant proof of work to an attacker. The BCrypt+SHA256 combination looks a bit more complex, but if you have ready-made implementations of these two and would have to roll your own PBKDF2 implementation (the PBKDF2 built into .NET is hardcoded to use SHA1, not SHA256), the first option would end up simpler. I see one advantage to PBKDF2 when implemented with a 256-bit HMAC; The actual BCrypt hash is only 192 bits, so that, and not 256 bits, is the maximum amount of entropy inherent in the BCrypt+SHA256 combo instead of a true maximum of 256 bits with PBKDF2-SHA256. BCrypt+SHA256 would still be better than the 160-bit Rfc2898DeriveBytes implementation of PBKDF2 in .NET, and even 128 bits, produced by truncating or XOR-folding any of the above hashes, is plenty secure enough with a good AES AEAD mode.

Opinions?

  • PBKDF2 is not supposed to be used for storing passwords, but to create encryption keys from passwords. bcrypt is IIRC meant to be used for password storage. – Henning Klevjer Jan 23 '13 at 9:54
  • 1
    Clearly, but that doesn't necessarily mean that neither can do the other's job. I think the questions stands; how would a BCrypt digest hashed with SHA-256 (as a single logical "unit of work"; the BCrypt hash wouldn't be used or found separately) fare as a means of password-based key derivation as compared to PBKDF2-SHA256? – KeithS Jan 24 '13 at 22:38
2

Simply hashing the BCrypt digest with SHA-256 will trivially expose encryption keys if your password database is compromised. Using the PBKDF2 of the password itself for encryption keys prevents this.

Of course, there are drawbacks. With the described scheme, the server can perform cryptographic operations with the user's key at any time, which may be desirable or necessary. When the PBKDF2 of the user's password is used, the server can't regenerate this key without the user providing his/her password.

  • I think that, as used in the referenced question, the BCrypt hash is never used or stored separately; whenever the BCrypt is calculated, it's immediately hashed again with SHA-256 before anything else is done with it (the scheme appears to be for password-based file encryption, not necessarily for user authentication). So, I don't think that your first concern applies in this case (though it's a valid point that the BCrypt and its SHA-256 hash should never be used independently). – KeithS Jan 23 '13 at 15:24
  • Yes, I see that now. It's strange to see BCrypt used as anything other than for password digesting (as opposed to key derivation, which it's doing here). You would have to strip out and preserve the salt, at the very least, in order to have reproducible BCrypt digests. – Stephen Touset Jan 23 '13 at 18:26
0

Bcrypt already preserves the salt so it seems the problem we're trying to solve here is the limited entropy from the standard 184 bit digest verses the 256 in the question.

I would argue that changing the implementation to get a few extra bits of entropy is a risk that far outweighs the potential gain:

The reward is overstated as the computational power involved in the brute forcing of a 184-bit bcrypt hash with a substantial work factor (1 second or more) is fundamentally prohibitive, even with good word lists. Sure 256 bits is also fundamentally prohibitive, but it's up the end of orders of magnitude where you don't get any added protection and given the risks it's not worth it.

The better thing to do is stick with the stock bcrypt implementation and choose a larger work factor, the largest work factor that the UX of your system can tolerate. This will ensure the lowest risk with forward planning and avoid mistakes with how your passwords are hashed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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