2 ms·
Your point 1 seems wrong. SHA-512 is constant time for any reasonable password length and any reasonable implementation. It hashes 1024-bit blocks in constant
by jlokier 5y ago
Your point 1 seems wrong. SHA-512 is constant time for any reasonable password length and any reasonable implementation. It hashes 1024-bit blocks in constant time, as it only uses 64-bit word operations such as add, shift, xor etc in a fixed order with fixed constants. There are no input data-dependent lookups, or other variable-time operations.
If you are considering the string copy that happens when the unhashed password is copied into the block to be variable time, probably you shouldn't count that against SHA-512 because there will be variable-length string operations before bcrypt starts its hashing too. Not to mention parsing it out of HTTP parameters or reading it from a GUI control. (If you really care about timing observations, perhaps you'd pre-hash the password on the client so what is transmitted is fixed-length).
Point 2 is of course a real problem. Though to be honest I've always regarded the NUL check and (sometimes, implementation-dependent) maximum length as unnecessary, arbitrary flaws in bcrypt - so bcrypt gets the blame. On grounds of purity and doing the right thing, I refuse to use raw bcrypt, and in fact I use: SHA-512 -> Base64 -> bcrypt when password hashing.
Does that make me wrong? Only if Dropbox is wrong (I hope they just forgot to mention Base64 in their old security article.)
- bhaney 5y ago> Your point 1 seems wrong. SHA-512 is constant time for any reasonable password length and any reasonable implementation. I'm aware of this, and it's why there's a "technically" in my original point. Of course in practice it makes no difference, and I consider the better use of bcrypt's input space when prehashing to outweigh leaking a pretty useless amount of side-channel information for extraordinarily long passwords. Though as a follow up anecdote, one of the engineers there had set a 300kB password to test the prehashing implementation, and just continued to use it (via password manager). He was potentially leaking a bit of timing information. I'm not even sure if a password that long made a timing difference that was detectable through network jitter, but if it did and some hypothetical attacker was able to learn that his password was hundreds of kilobytes long, well... good luck. > in fact I use: SHA-512 -> Base64 -> bcrypt when password hashing. Does that make me wrong? No, using a base64 representation of the sha hash makes your scheme perfectly reasonable. Also note that the base64 representation of sha512 is a bit longer than the typical bcrypt input length, so you're shrinking the collision space somewhat by truncating your sha hash. Certainly not enough that it would matter at all, just a point I find interesting. Hypothetically, a binary representation with a pass that removed or replaced NUL bytes would preserve more entropy, but we're well past the point where it matters and would be playing with fire to consider that complexity.
- jlokier 5y ago256 bits is enough collision resistance, so I don't mind truncating SHA-512, even down to 256 bits. If you find collision space reduction interesting, then you might find it even more interesting that truncating SHA-512 makes it more secure not less. This (and the higher rounds safety margin) is why I choose truncated SHA-512 over SHA-256 for this sort of application, even though the number of output bits is the same: Check out the red boxes on https://en.wikipedia.org/wiki/Template:Comparison_of_SHA_functions https://en.wikipedia.org/wiki/Template:Comparison_of_SHA_fun...