This article doesn't feel very well done to me. He writes: "The first cipher I'd suggest you consider besides bcrypt is PBKDF2."
PBKDF2 is not a cipher. It's a KDF, and it's almost always used with an HMAC or a cryptographic hash rather than a cipher. The thesis of this article seems to be "PBKDF2 is well understood, where bcrypt is not." In fact, the opposite is probably true.
bcrypt uses a block cipher (blowfish) to create its underlying compression function. Block ciphers are extremely well understood, have been studied to death for years, and are modeled on extremely well understood constructs. They can be used to create cryptographic hash functions, but usually aren't, because they're slow (which we don't care about in this case).
Cryptographic hash functions, by contrast, are not well understood at all. They are "magic" in many ways, and aren't modeled after anything. Many more "bad things" happen in this space than in the block cipher space. The only reason people mess with them at all is because they're faster than block ciphers, which again, we don't care about in this case.
The other appeal to PBKDF2 is because it "comes from RSA." This doesn't feel like an extremely compelling argument, but if we were going to believe it, then why not use the PKCS#12 KDF? PBKDF2 was proposed in PKCS#5, and "12" is a larger number than "5", so if we're going to do what RSA tells us we should do, they're essentially saying we shouldn't actually use PBKDF2.
Cryptographic hash functions, by contrast, are not well understood at all. They are "magic" in many ways, and aren't modeled after anything. Many more "bad things" happen in this space than in the block cipher space.
Is this a common opinion amongst practitioners? The opposite philosophy (e.g., that a random oracle is a "weaker object" than an ideal cipher) underlies some lines of work in the theoretical cryptography literature.
> I write this post because I've noticed a sort of "JUST USE BCRYPT" cargo cult... This is absolutely the wrong attitude to have about cryptography.
No. This is incorrect. This is exactly the right attitude for most developers to have about cryptography, because on a subject as complex as cryptography most developers (including me!) are nowhere near smart enough to understand the ins and outs.
Encouraging people to make their own decisions on subjects they aren't equipped to understand fully is dangerous advice. It leads to all sorts of bad outcomes. People who have to choose between options they don't really understand end up choosing things at random, or on the basis of incomplete or misleading information, or getting seized up by the need to make a choice and choosing nothing at all.
This makes cryptography one of the very few cases where a cargo-cult approach is better than the alternatives. A simple message that "this is the approach people smarter than you agree is correct, use it," repeated consistently, will help more people more completely than dumping them into the deep end of the crypto pool ever will.
> No. This is incorrect. This is exactly the right attitude for most developers to have about cryptography, because on a subject as complex as cryptography most developers (including me!) are nowhere near smart enough to understand the ins and outs.
I hear that a lot, and it always reminds me of Jante Law[1]. Its a disservice to keep telling people that they are too stupid to understand something. Too ignorant, perhaps - that can be remedied - but everyone is not too stupid to understand crypto. It's simply another field, mostly mathematical, and goof-ups are easy to make and often very costly.
edit: I should also make another point. Cryptography is exactingly and excruciatingly hard to do at industrial strength. I am not recommending people go out and roll their own crypto for production systems. It's possible for the initiated to do right; it's possible to get initiated. The uninitiated almost certainly will goof. I'd like to further point out [2], which is a discussion and break on a homebrew crypto, for a taste of the difficulties and mathematical sophistication needed.
What happens if that method is flawed? You hear about it as soon as it's discovered and it gets fixed quick.
Option 2: Roll your own stack based on a personal understanding of cryptography.
What happens if that method is flawed? Perhaps only you and an attacker could possibly know such a thing. You have to be ever vigilant and you have to acquire an incredible amount of crypto knowledge. If you ever leave the company they are pretty much fucked from then on until whatever you wrote is replaced.
The point here is that this particular cargo cult around bcrypt (one subscribed to by some really loud people) has a shaky foundation and does not deserve its reputation. He's offering alternatives that have been better studied.
So, by all means, subscribe to a cargo cult for crypto. But pick the cult carefully.
One more example: pseudorandom number generation (non-cryptographic). There are lots of algorithms out there, and lots more you could design, but the Mersenne twister has pretty much become the first-choice algorithm.
Especially with linear congruential generators, it's easy for people who don't know what they're doing to add "extra randomization" that makes the resulting numbers worse than the originals.
It's better for most people to not get fancy and use the standard algorithm.
It is very dangerous to be ignorant about critical computer science fields like cryptography and just go with the cult.
I'm not saying you should build your own cryptography, but a good hacker (or a good engineer how we call them in early 90s) should understand difference between bcrypt, PBKDF2, and scrypt. At least to understand why bcrypt is better than salt+SHA-1. And some other aspects of security.
However, if somebody has no clue about cryptography and security then she/he should go with bcrypt - but I'm not sure if that person should be responsible or in business of storing somebody's critical data at all.
Why not just say, "people who spent a lot of their time studying cryptography strongly recommend this approach. They feel the approach that you are considering is simply insecure."?
Framing things in terms of intelligence isn't going to win anyone over, if that's your goal. And it probably isn't accurate, either.
bcrypt has the advantage of being both very good, and also broadly available on web platforms. scrypt does not yet have that advantage; when it does, I will start saying "just use scrypt".
But the simple fact is: all three of these functions are fine. ANY of them is a huge step forward from what people do without them.
"Just use bcrypt" is 1000x more effective as a meme than "just use adaptive hashing" (which is what all these constructions are).
So, while I have few specific technical qualms with this article (e.g. why do I care whether something is a PKCS standard or not?), the overall message is a bit hyperbolic.
You seem to be speaking only to its compute time -- what do you say to the article's claim that bcrypt has a higher probability of having an unexpected attack that mitigates its computational complexity?
Also, since all of these algorithms have adjustable work factors, what does it even mean to say that one is stronger than another? Couldn't you just calibrate the work factors so that they are equivalently strong? Though naturally scrypt has strength in another dimension also (memory).
Can you elaborate a little bit on this? Or point to a reference. Wikipedia mentions that PBKDF2 is easier to implement with ASICs or GPUs. Is that the primary reason?
Isn't that a self-fulfilling prophecy? If you buying into the "just use bcrypt" idea, how will scrypt ever change the fact that it's not widely available on the web?
I'm a web developer, so while security is obviously a huge concern, it's not my main area of expertise. I don't have the knowledge to evaluate the pros and cons of each cipher, and the situations in which it's appropriate to use each one.
It would be wonderful if someone with more knowledge of the subject could throw up a 1-page site with an appropriate security choice (or a few choices with situations in which each would be more acceptable) for a given range of situations, to establish a 'sane default', taking into account their availability on a number of platforms and programming languages.
For example:
Need to sign a message? Use HMAC-SHA1
Need to checksum a file? Use SHA-1
Need to hash a password? Use bcrypt
Need to transmit data over a network? Use SSH2
Need to secure HTTP? Use SSL 1.2 with (these ciphers in order of preference)
Need to secure home WiFi? Use WPA2-PSK
Need to encrypt files? Use GnuPG
Need to do (this type) of encryption? Use CBC. For (this type), use ECB
Need to create a TrueCrypt volume? Use (this cipher) with (this many) bits.
Need to sign a message? Using S/MIME or PGP.
Need to checksum a file? Use SHA256.
Need to hash a password? Use bcrypt, scrypt, or PBKDF2.
Need to transmit data over a network? Use HTTPS/TLS
Need to secure HTTP? Use HTTPS/TLS, preferring AES in CTR and then CBC.
Need to secure home WiFi? Use WPA2PSK.
Need to encrypt files? Use any implementation of PGP.
Need to do (this type) of encryption? Use PGP. Never use AES directly. Never use ECB for anything.
Need to create a TrueCrypt volume? Can't help you; we use PGP.
I guess the question is - who do you trust to make these calls?
In this case, the answer probably is OWASP which is a great and often overlooked resource, contributed to by a lot of experts in the area. They have a lot of pages in their wiki that address crypto concerns...
I think he meant it hasn't undergone the same level of public scrutiny. You've certainly spent ample time researching it, and it's obviously been tested, but possibly not as much something like AES.
> […] with an academic pedigree from RSA Labs, you know, the guys who invented much of the cryptographic ecosystem we use today.
Appeal to authority fails a little bit when RSA opens random Excel attachments from unknown untrusted sources - attached to an email that have to be retrieved from the junk mail folder.
EDIT: As other commentators point out, I am wrong to suggest that anything coming from RSA Labs is somehow "weak" because someone at RSA fell for a phishing attack. I do find it odd that a security article suggests "These people are good; they did 'this thing' which everyone uses". That's not a great way to approach choosing crypto components. Even experts make mistakes.
I guess it's hip to have an opinion, but JUST USE BCRYPT. It's secure and available. Don't spend time thinking about it, just use bcrypt, it does everything you want, move on to something more worth your time.
Unless you're some blogger who needs to generate some page views, then pick some obscure topic like how to store password hashes and rake muck.
I wouldn't exactly call "just use bcrypt" a cargo cult. It has had real benefits to the web dev community because it factors down to "don't store it in plain text or use MD5 or something".
Several people working on small projects have already come to me and asked me "what's this bcrypt thing? should I use it here?" I guarantee these folks would have just stored it plaintext otherwise. So I've directly observed the mantra making stuff safer. Win.
Microsoft uses PBKDF2 for newer domain cached credentials (DCC2). These password hashes are stored in the registry of Windows clients (laptops and desktops) and allow users to logon when the domain is unavailable. They use 10240 iterations. It's very compute intensive to crack... roughly 330 guesses per second. Great article BTW!
Edit: I only post this to add to the examples of who uses PBKDF2 in addition to what the article lists.
Oddly enough, this article prompted me to setup bcrypt hashing for our unreleased app. I tend to not follow the tide when it comes to people screaming on the internet about something. People get highly emotional about the "next big thing" and defend with every ounce of willpower the decisions they've made. While I understand this mentality, it can make it hard to be objective.
Seeing an article where someone disagrees with the buzzing hive mind is always refreshing for me and made me actually consider, for the first time, that an algorithm aside from sha1(app_salt + user_salt + password) would be a good idea.
I did some research and decided that for PHP, bcrypt is the absolute easiest option to implement. scrypt is too new, PBKDF2 while administratively accepted has much less info on using it in PHP than bcrypt does.
So while I ultimately ended up disagreeing with the author, the article was invaluable in the end.
As stated in the article, a popular stance on Hacker News and Stack Overflow is "USE BCRYPT". It's chanted to crypto-noobs and webdevs as a simple-to-use library for password storage that is more secure than MD5/SHA/Whatever hashing, and with built-in salts.
The whole point of this article is to say that, in fact, there are other options.
I wasn't aware that anyone suggested using bcrypt for key derivation. The idea, as I understood it, was to avoid writing your own password hashing implementation. Bcrypt is a complete password-hashing implementation, so use it, rather than cobbling something together yourself. This is the standard advice for cryptographic software.
PBKDF2 isn't a password hash: the specification doesn't define a storage format for iterated, salted password hashes. It's not that hard to invent one if you already specialize in writing cryptographic software, but most programmers still shouldn't be doing that. It's just too easy to make mistakes that go unnoticed until it's too late.
If you insist on using PBKDF2, then I suggest using my PBKDF2.crypt() implementation at https://github.com/dlitz/python-pbkdf2. I'm not a cryptologist, but I'm the maintainer of PyCrypto, so presumably I can be trusted to do a better-than-average job of this sort of thing. If people want, I'll write a proper spec and add SHA256 support with a different algorithm identifier (the current implementation still uses SHA1).
But really, if you need a password hash, just use bcrypt and get back to writing the code that actually provides value to your user base and differentiates you from your competitors. Bcrypt is good enough for now. This advice might change in the future, so do pay attention, but for now, just use bcrypt.
So the author says to use PBKDF2 because it's researched and tested better than bcrypt, and then suggests scrypt as another alternative despite having, from what I can tell, less research done on it than bcrypt.
The crypto space can be intimidating to your average dev, but almost every app needs some sort of protection (at least for user information). I think the author is fair in wanting to push for the "default" to be PBKDF2 instead of bcrypt, but should he really be advocating a less-tested function in the same article?
While we agree on the fact that using either of the three can't be a bad thing, I'd like to give my opinion on why I favor PBKDF2 over bcrypt, and probably even over scrypt, although I admit the "memory-hardness" of the latter makes it superior in principle. But still, my reasons for going with PBKDF2:
It's not just that it's endorsed by RSA, no it's actually the NIST recommendation for password hashing and I find it rather unfair that people on this thread turn that against it!
It's the same argument why we generally recommend AES over let's say Twofish or Serpent. We all agreed here that in crypto it's a good thing to be mainstream. And being recommended by NIST makes you Justin Bieber, or not? Standard algorithms may be poor, true, but being a standard has one important advantage: most of the public scrutiny goes into the standard. Much more money and fame there. So it's much more likely that the public will get to know about a flaw in the standard faster than it will get to know about flaws in non-standard algorithms. And that's why I follow standards - even if it's a crappy algorithm, I will know immediately when it's broken and I can react by replacing it right away. The time between an algorithm gets broken and the fact becoming public knowledge is potentially higher the less common an algorithm is. And the time in between being broken and being public knowledge is the most dangerous in my opinion.
I'd like to point out that bcrypt is not equal to Blowfish. It piggybacks on Blowfish's key setup. But note that it just piggybacks, on top of that it further extends the original key setup. Blowfish's key setup was probably never invented to do what bcrypt does now, and the last 30min of googling have not brought up any papers about bcrypt cryptanalysis. Compare that to HMAC. Compare that to using PBKDF2 with HMAC SHA-3 when it's out. I'm not saying that Blowfish or any of its parts are bad, but if not PBKDF2 itself, but then most certainly its building blocks have received a lot more analysis than bcrypt or scrypt. With SHA-3 on the horizon the research community knows a lot more about hash algorithms and there is a lot of research going into these topics. That's why I personally feel safer with a construction that maybe in itself has not received more research than the other two alternatives, but where its building blocks almost certainly have, unless somebody proves me wrong. And when that happens, I'll stand happily corrected and will use the next standard.
"that won't help you if an attack is discovered which mitigates bcrypt's computational complexity."
AND you lose control of your database. Even if I had a magic instant bcrypt reverser, it does me no good if I don't have the hashes. You cannot be compromised by a bcrypt mistake, it would only make your already existing compromise slightly worse.
To be honest, if anybody breaks into your web application it is very unlikely to be because they broke any encryption. SQL injection or man in the middle type attacks are far far more likely.
What you need out of an encryption package is in the event of being tested for PCI compliance or any legal liability investigation into a breach. You need to be able to say "all of our encryption is done with bcrypt , it's the industry standard an complies with X Y and Z".
Suppose hypothetically you knew everyone using your service used a strong password. Say they all have good password managers that generate 40 character random passwords for them.
Is there then any need to do more than a simple salted hash? (Remember, the hypothesis is that all your users are using strong passwords).
The difference in that (obviously unrealistic) case is (I think?) between a cost per password of hundreds of thousands of dollars versus high tens of millions of dollars.
PBKDF2 has had longer public exposure, and also features an adjustable CPU work factor (though with a lower theoretical safety-to-compute-time than bcrypt).
scrypt is newer, but features both a CPU and memory work factor (memory-hard algorithm), and is algorithmically superior to both.
Why, exactly, do you think PBKDF2 is a more sensible default than bcrypt?
(If scrypt was trivially installable from a gem for Ruby, easy_install for Python, CPAN for Perl, a jar for Java and a .NET assembly for Microsoft, and all those bits came from sources where I didn't have to manually audit them and make personal attestations for their quality when I recommended them to clients, I would immediately stop recommending bcrypt).
[+] [-] moxie|14 years ago|reply
PBKDF2 is not a cipher. It's a KDF, and it's almost always used with an HMAC or a cryptographic hash rather than a cipher. The thesis of this article seems to be "PBKDF2 is well understood, where bcrypt is not." In fact, the opposite is probably true.
bcrypt uses a block cipher (blowfish) to create its underlying compression function. Block ciphers are extremely well understood, have been studied to death for years, and are modeled on extremely well understood constructs. They can be used to create cryptographic hash functions, but usually aren't, because they're slow (which we don't care about in this case).
Cryptographic hash functions, by contrast, are not well understood at all. They are "magic" in many ways, and aren't modeled after anything. Many more "bad things" happen in this space than in the block cipher space. The only reason people mess with them at all is because they're faster than block ciphers, which again, we don't care about in this case.
The other appeal to PBKDF2 is because it "comes from RSA." This doesn't feel like an extremely compelling argument, but if we were going to believe it, then why not use the PKCS#12 KDF? PBKDF2 was proposed in PKCS#5, and "12" is a larger number than "5", so if we're going to do what RSA tells us we should do, they're essentially saying we shouldn't actually use PBKDF2.
[+] [-] tptacek|14 years ago|reply
[+] [-] bascule|14 years ago|reply
[+] [-] cdavidcash|14 years ago|reply
Is this a common opinion amongst practitioners? The opposite philosophy (e.g., that a random oracle is a "weaker object" than an ideal cipher) underlies some lines of work in the theoretical cryptography literature.
[+] [-] smacktoward|14 years ago|reply
No. This is incorrect. This is exactly the right attitude for most developers to have about cryptography, because on a subject as complex as cryptography most developers (including me!) are nowhere near smart enough to understand the ins and outs.
Encouraging people to make their own decisions on subjects they aren't equipped to understand fully is dangerous advice. It leads to all sorts of bad outcomes. People who have to choose between options they don't really understand end up choosing things at random, or on the basis of incomplete or misleading information, or getting seized up by the need to make a choice and choosing nothing at all.
This makes cryptography one of the very few cases where a cargo-cult approach is better than the alternatives. A simple message that "this is the approach people smarter than you agree is correct, use it," repeated consistently, will help more people more completely than dumping them into the deep end of the crypto pool ever will.
[+] [-] pnathan|14 years ago|reply
I hear that a lot, and it always reminds me of Jante Law[1]. Its a disservice to keep telling people that they are too stupid to understand something. Too ignorant, perhaps - that can be remedied - but everyone is not too stupid to understand crypto. It's simply another field, mostly mathematical, and goof-ups are easy to make and often very costly.
edit: I should also make another point. Cryptography is exactingly and excruciatingly hard to do at industrial strength. I am not recommending people go out and roll their own crypto for production systems. It's possible for the initiated to do right; it's possible to get initiated. The uninitiated almost certainly will goof. I'd like to further point out [2], which is a discussion and break on a homebrew crypto, for a taste of the difficulties and mathematical sophistication needed.
[1] http://en.wikipedia.org/wiki/Jante_Law
[2]http://phrack.org/issues.html?issue=64&id=10#article
[+] [-] InclinedPlane|14 years ago|reply
What happens if that method is flawed? You hear about it as soon as it's discovered and it gets fixed quick.
Option 2: Roll your own stack based on a personal understanding of cryptography.
What happens if that method is flawed? Perhaps only you and an attacker could possibly know such a thing. You have to be ever vigilant and you have to acquire an incredible amount of crypto knowledge. If you ever leave the company they are pretty much fucked from then on until whatever you wrote is replaced.
Don't roll your own system.
[+] [-] tpsreport|14 years ago|reply
So, by all means, subscribe to a cargo cult for crypto. But pick the cult carefully.
[+] [-] mturmon|14 years ago|reply
Especially with linear congruential generators, it's easy for people who don't know what they're doing to add "extra randomization" that makes the resulting numbers worse than the originals.
It's better for most people to not get fancy and use the standard algorithm.
[+] [-] bascule|14 years ago|reply
[+] [-] gfaremil|14 years ago|reply
I'm not saying you should build your own cryptography, but a good hacker (or a good engineer how we call them in early 90s) should understand difference between bcrypt, PBKDF2, and scrypt. At least to understand why bcrypt is better than salt+SHA-1. And some other aspects of security.
However, if somebody has no clue about cryptography and security then she/he should go with bcrypt - but I'm not sure if that person should be responsible or in business of storing somebody's critical data at all.
[+] [-] pleasebehonest|14 years ago|reply
Why not just say, "people who spent a lot of their time studying cryptography strongly recommend this approach. They feel the approach that you are considering is simply insecure."?
Framing things in terms of intelligence isn't going to win anyone over, if that's your goal. And it probably isn't accurate, either.
[+] [-] tptacek|14 years ago|reply
scrypt is better than bcrypt.
bcrypt has the advantage of being both very good, and also broadly available on web platforms. scrypt does not yet have that advantage; when it does, I will start saying "just use scrypt".
But the simple fact is: all three of these functions are fine. ANY of them is a huge step forward from what people do without them.
"Just use bcrypt" is 1000x more effective as a meme than "just use adaptive hashing" (which is what all these constructions are).
So, while I have few specific technical qualms with this article (e.g. why do I care whether something is a PKCS standard or not?), the overall message is a bit hyperbolic.
[+] [-] cperciva|14 years ago|reply
By roughly a factor of 5.
scrypt is better than bcrypt.
By roughly a factor of 4000.
why do I care whether something is a PKCS standard or not?
You don't care, and I don't care, but I'm sure you know lots of companies which do care (especially since PBKDF2 is a NIST standard too).
[+] [-] haberman|14 years ago|reply
You seem to be speaking only to its compute time -- what do you say to the article's claim that bcrypt has a higher probability of having an unexpected attack that mitigates its computational complexity?
Also, since all of these algorithms have adjustable work factors, what does it even mean to say that one is stronger than another? Couldn't you just calibrate the work factors so that they are equivalently strong? Though naturally scrypt has strength in another dimension also (memory).
[+] [-] bdhe|14 years ago|reply
Can you elaborate a little bit on this? Or point to a reference. Wikipedia mentions that PBKDF2 is easier to implement with ASICs or GPUs. Is that the primary reason?
[+] [-] j_baker|14 years ago|reply
[+] [-] bascule|14 years ago|reply
[+] [-] nextparadigms|14 years ago|reply
[+] [-] steveh73|14 years ago|reply
It would be wonderful if someone with more knowledge of the subject could throw up a 1-page site with an appropriate security choice (or a few choices with situations in which each would be more acceptable) for a given range of situations, to establish a 'sane default', taking into account their availability on a number of platforms and programming languages.
For example:
[+] [-] tptacek|14 years ago|reply
[+] [-] chrismsnz|14 years ago|reply
In this case, the answer probably is OWASP which is a great and often overlooked resource, contributed to by a lot of experts in the area. They have a lot of pages in their wiki that address crypto concerns...
https://www.owasp.org/index.php/Guide_to_Cryptography
https://www.owasp.org/index.php/Cryptographic_Storage_Cheat_...
https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet
[+] [-] cperciva|14 years ago|reply
I think we may have different notions of what "poorly researched" means.
[+] [-] zheng|14 years ago|reply
[+] [-] DanBC|14 years ago|reply
> […] with an academic pedigree from RSA Labs, you know, the guys who invented much of the cryptographic ecosystem we use today.
Appeal to authority fails a little bit when RSA opens random Excel attachments from unknown untrusted sources - attached to an email that have to be retrieved from the junk mail folder.
(http://blogs.rsa.com/rivner/anatomy-of-an-attack/)
EDIT: As other commentators point out, I am wrong to suggest that anything coming from RSA Labs is somehow "weak" because someone at RSA fell for a phishing attack. I do find it odd that a security article suggests "These people are good; they did 'this thing' which everyone uses". That's not a great way to approach choosing crypto components. Even experts make mistakes.
[+] [-] justin_vanw|14 years ago|reply
Unless you're some blogger who needs to generate some page views, then pick some obscure topic like how to store password hashes and rake muck.
[+] [-] baq|14 years ago|reply
multiple things come to mind:
- Millions Of Flies Can't Be Wrong
- Citation Needed
- JUST USE SCRYPT
etc.
[+] [-] zobzu|14 years ago|reply
That's the way to go.
(and i bet many won't even notice the sarcasm)
Freaking hell, do critise, do research, and that apply to everything, not just crypto. It's not rocket science.
[+] [-] noonespecial|14 years ago|reply
Several people working on small projects have already come to me and asked me "what's this bcrypt thing? should I use it here?" I guarantee these folks would have just stored it plaintext otherwise. So I've directly observed the mantra making stuff safer. Win.
[+] [-] 16s|14 years ago|reply
Edit: I only post this to add to the examples of who uses PBKDF2 in addition to what the article lists.
[+] [-] orthecreedence|14 years ago|reply
Seeing an article where someone disagrees with the buzzing hive mind is always refreshing for me and made me actually consider, for the first time, that an algorithm aside from sha1(app_salt + user_salt + password) would be a good idea.
I did some research and decided that for PHP, bcrypt is the absolute easiest option to implement. scrypt is too new, PBKDF2 while administratively accepted has much less info on using it in PHP than bcrypt does.
So while I ultimately ended up disagreeing with the author, the article was invaluable in the end.
[+] [-] jgrahamc|14 years ago|reply
I'm confused. Why would I pick bcrypt as a key derivation function when there are nice key derivation functions out there that are widely documented?
[+] [-] lhnn|14 years ago|reply
The whole point of this article is to say that, in fact, there are other options.
[+] [-] dlitz|14 years ago|reply
PBKDF2 isn't a password hash: the specification doesn't define a storage format for iterated, salted password hashes. It's not that hard to invent one if you already specialize in writing cryptographic software, but most programmers still shouldn't be doing that. It's just too easy to make mistakes that go unnoticed until it's too late.
If you insist on using PBKDF2, then I suggest using my PBKDF2.crypt() implementation at https://github.com/dlitz/python-pbkdf2. I'm not a cryptologist, but I'm the maintainer of PyCrypto, so presumably I can be trusted to do a better-than-average job of this sort of thing. If people want, I'll write a proper spec and add SHA256 support with a different algorithm identifier (the current implementation still uses SHA1).
But really, if you need a password hash, just use bcrypt and get back to writing the code that actually provides value to your user base and differentiates you from your competitors. Bcrypt is good enough for now. This advice might change in the future, so do pay attention, but for now, just use bcrypt.
[+] [-] ceol|14 years ago|reply
The crypto space can be intimidating to your average dev, but almost every app needs some sort of protection (at least for user information). I think the author is fair in wanting to push for the "default" to be PBKDF2 instead of bcrypt, but should he really be advocating a less-tested function in the same article?
[+] [-] tptacek|14 years ago|reply
[+] [-] emboss|14 years ago|reply
It's not just that it's endorsed by RSA, no it's actually the NIST recommendation for password hashing and I find it rather unfair that people on this thread turn that against it!
It's the same argument why we generally recommend AES over let's say Twofish or Serpent. We all agreed here that in crypto it's a good thing to be mainstream. And being recommended by NIST makes you Justin Bieber, or not? Standard algorithms may be poor, true, but being a standard has one important advantage: most of the public scrutiny goes into the standard. Much more money and fame there. So it's much more likely that the public will get to know about a flaw in the standard faster than it will get to know about flaws in non-standard algorithms. And that's why I follow standards - even if it's a crappy algorithm, I will know immediately when it's broken and I can react by replacing it right away. The time between an algorithm gets broken and the fact becoming public knowledge is potentially higher the less common an algorithm is. And the time in between being broken and being public knowledge is the most dangerous in my opinion.
I'd like to point out that bcrypt is not equal to Blowfish. It piggybacks on Blowfish's key setup. But note that it just piggybacks, on top of that it further extends the original key setup. Blowfish's key setup was probably never invented to do what bcrypt does now, and the last 30min of googling have not brought up any papers about bcrypt cryptanalysis. Compare that to HMAC. Compare that to using PBKDF2 with HMAC SHA-3 when it's out. I'm not saying that Blowfish or any of its parts are bad, but if not PBKDF2 itself, but then most certainly its building blocks have received a lot more analysis than bcrypt or scrypt. With SHA-3 on the horizon the research community knows a lot more about hash algorithms and there is a lot of research going into these topics. That's why I personally feel safer with a construction that maybe in itself has not received more research than the other two alternatives, but where its building blocks almost certainly have, unless somebody proves me wrong. And when that happens, I'll stand happily corrected and will use the next standard.
[+] [-] tedunangst|14 years ago|reply
AND you lose control of your database. Even if I had a magic instant bcrypt reverser, it does me no good if I don't have the hashes. You cannot be compromised by a bcrypt mistake, it would only make your already existing compromise slightly worse.
[+] [-] tptacek|14 years ago|reply
You could use a similar argument to recommend Elliptic Curve over RSA, or RSA over Elliptic Curve.
[+] [-] jiggy2011|14 years ago|reply
What you need out of an encryption package is in the event of being tested for PCI compliance or any legal liability investigation into a breach. You need to be able to say "all of our encryption is done with bcrypt , it's the industry standard an complies with X Y and Z".
[+] [-] antihero|14 years ago|reply
[+] [-] tzs|14 years ago|reply
Is there then any need to do more than a simple salted hash? (Remember, the hypothesis is that all your users are using strong passwords).
[+] [-] tptacek|14 years ago|reply
[+] [-] SkyMarshal|14 years ago|reply
PBKDF2 has had longer public exposure, and also features an adjustable CPU work factor (though with a lower theoretical safety-to-compute-time than bcrypt).
scrypt is newer, but features both a CPU and memory work factor (memory-hard algorithm), and is algorithmically superior to both.
[+] [-] _delirium|14 years ago|reply
I don't know whether or not it's had more public exposure, but I don't think it's had longer public exposure. Afaik, bcrypt's canonical reference document is the June 1999 Usenix paper (http://static.usenix.org/event/usenix99/provos/provos_html/i...), while PBKDF2's is the September 2000 RFC (http://www.ietf.org/rfc/rfc2898.txt).
[+] [-] unknown|14 years ago|reply
[deleted]
[+] [-] tptacek|14 years ago|reply
(If scrypt was trivially installable from a gem for Ruby, easy_install for Python, CPAN for Perl, a jar for Java and a .NET assembly for Microsoft, and all those bits came from sources where I didn't have to manually audit them and make personal attestations for their quality when I recommended them to clients, I would immediately stop recommending bcrypt).