Bcrypt is a password hash, not a KDF, which is the way it was used in this API. It's super unclear to me why they wanted a string-based KDF here at all; does anyone have more context? I've in the past been annoying about saying I think we should just call all password hashes "KDFs", but here's a really good illustration of why I was definitely wrong about that. A KDF is a generally-useful bit of cryptography joinery;…
The value is the combination of userid, username, and password, so in threads on other platforms people have hypothesised that the developer tried to play it safe and use a password hash because of the password's presence. Also I'm not sure the average developer understands the distinction.
Okta Bcrypt incident lessons for designing better APIs
41–50 of 169 posts
Re: Okta Bcrypt incident lessons for designing better APIs
#42Earlier quoted context omitted.
Yeah, I think both of the following would have worked if they wanted the password involved in a cache key and they wanted bcrypt to be used: * bcrypt(SHA-512(PW || stuff)) * SHA(stuff || bcrypt(PW)) Disclaimer: Not cryptography advice. It's still unclear to me why the password is in there.
hmac-bcrypt solves that problem very well, and should replace plain bcrypt: https://github.com/epixoip/hmac-bcrypt
An authentication company should have known this...
Re: Okta Bcrypt incident lessons for designing better APIs
#43Earlier quoted context omitted.
Yes, the hashed payload contained a password, so presumably they didn't want to just SHA it.
Begs the question of why the payload contained a password, right?
Re: Okta Bcrypt incident lessons for designing better APIs
#44Re: Okta Bcrypt incident lessons for designing better APIs
#45Earlier quoted context omitted.
hmac-bcrypt solves that problem very well, and should replace plain bcrypt: https://github.com/epixoip/hmac-bcrypt
HMAC-bcrypt is a more complicated version of the first construction I proposed, and it would need a rigorous cryptanalysis if someone wanted to actually use it in production. It sounds like Okta actually wanted PBKDF2(stuff) here. An authentication company should have known this...
Re: Okta Bcrypt incident lessons for designing better APIs
#46Bcrypt is a password hash, not a KDF, which is the way it was used in this API. It's super unclear to me why they wanted a string-based KDF here at all; does anyone have more context? I've in the past been annoying about saying I think we should just call all password hashes "KDFs", but here's a really good illustration of why I was definitely wrong about that. A KDF is a generally-useful bit of cryptography joinery;…
Re: Okta Bcrypt incident lessons for designing better APIs
#47The analogy is something like creating a hash map whose insert function computes the slot for the key and unconditionally puts the value there instead of checking if the keys are the same during a collision. No amount of tinkering with the hash function fixes this problem. The algorithm is wrong. A hashmap should survive and be correct even giving it a hash function that always returns 4.
Re: Okta Bcrypt incident lessons for designing better APIs
#48Weird take. Usernames are often chosen by the user. Less so in corporate world but definitely not unheard of
Re: Okta Bcrypt incident lessons for designing better APIs
#49> was used to generate the cache key where we hash a combined string of userId + username + password. Don't conceive your own cryptographic hacks. Use existing KDF designed by professionals.
Re: Okta Bcrypt incident lessons for designing better APIs
#50Reminds me of when I saw a junior developer calling SHA-1 on an incrementing integer ID, with no salt. We had a long talk about it, he thought it was too "scrambled" to allow anyone to recognize what was being done. He shouldn't have been so junior, he was 4 or 5 years into his career. I had to be the bad guy and override his decision without further discussing why it was a bad idea, and I really tried for a good 45…
[Im assuming the usual definition of salt where it is known by the attacker... a pepper would be fine]