9 ms·
Please stop hashing passwords
- NateDad 13y agoMy guess is that anyone who still does this does not actually read technology blogs or Hacker News. The answer for a long time now has been "use scrypt or bcrypt". I think that answer still holds (IANAC).
- kzrdude 13y agoHopefully the people behind password-hashing.net will give us an up to date recommendation when their contest concludes.
- rlpb 13y agoI get the impression that, even on HN, after some high profile database breach, people still ask "were they using hashed passwords?" rather than "were they using a key derivation function and if so which one with what parameters?". This tells me that the HN crowd still hasn't got it. My own attempt at this message: http://www.justgohome.co.uk/blog/2014/02/salting-hashing-and-key-derivation.html http://www.justgohome.co.uk/blog/2014/02/salting-hashing-and...
- NateDad 13y agoCertainly, it's a message that bears repeating. New devs enter the workforce every day.
- vertex-four 13y agoOr some variety of PBKDF2 if adhering to standards is more your thing, or you intend to market the security of your system to enterprise customers. The likes of Python's Django use this by default.
- NateDad 13y agoYes, right. Sometimes I think people (myself included) leave out PBKDF2 because it's hard to spell/pronounce. :)
- tragic 13y agoI might remember it now that I know KDF = key derivation function. Since the GP mentions Django, it's worth remembering in this connection that there are extra security concerns with expensive KDF algorithms. There was a vuln in Django where people could submit 'passwords' of arbitrary size - a 20 character password isn't a problem, but 1MB worth of text being expensively hashed a few times at once could be used as a nice DoS vector.[0] So there's more to the problem than just bunging in PBKDF2/bcrypt and forgetting about it. [0] https://www.djangoproject.com/weblog/2013/sep/15/security/ https://www.djangoproject.com/weblog/2013/sep/15/security/
- tptacek 12y agoEnterprise customers do not care about PKCS "standards" and don't as a rule really know much about password hashing. A good reason to use PBKDF2 instead of bcrypt is if your password hash needs to double as an actual key derivation function. Other than that, I can't think of any authentic good reasons to use it. It doesn't matter, though. PBKDF2, bcrypt, scrypt: all fine. Just stop using salted, peppered, or lightly-battered hashes.
- tim333 12y agoFor quite a while pleantyoffish.com sent me regular emails including "remember you password is"... in plain text. They seem have stopped now. Some evil hacker could have stolen my ever so valuable list of potential dates.
- ttflee 13y agoThe tl;dr from the article: > Stop associating “hashed” with “secure” when it comes to passwords. If you’re storing user credentials MD5-ed without salt, you’ve put an thumb tack in front of a steamroller - just a minor annoyance that won’t offer you any real security. You have to do it right or hashing means nothing. > Start relying on key derivation functions for password storage.[1] Are they perfect? Will they be the best practice in five years? Probably not, but they’re your best option when rolling your own user credential storage. > Don’t sacrifice security for performance. A slightly slower malloc in OpenSSL would have been much preferred, in my opinion, than the disaster that is Heartbleed. - [1] There’s a fair bit of dispute over the ideal KDF for storing passwords, but generally speaking, any of the three covered in this topic are popularly accepted options.
- DiabloD3 13y agoRe: slower malloc, there is no actual proof of, say, modern glibc's malloc implementation is slower in any useful measurement of the term. Heartbleed, however, didn't happen because someone failed benchmarking 101, it happened because someone failed bounds checking 101.
- kzrdude 13y agoThe point that I and others want to make, is that regardless of the ultimate cause of failure, we want to criticize the whole design approach. Security in layers needs conservative coding style, both safe and sound internal APIs, bounds checking and an overly cautious memory allocator. It's not just about finding and fixing bugs, but how to improve the whole process.
- chrisrohlf 12y agoIt is frustrating that the confusion around heartbleed and the OpenSSL free lists persists: http://blog.leafsr.com/2014/04/11/my-heart-is-ok-but-my-eyes-are-bleeding/ http://blog.leafsr.com/2014/04/11/my-heart-is-ok-but-my-eyes...
- oleganza 13y agoThe problem with expensive KDF on the server is that you are opening yourself to a higher risk of DoS. More computationally intensive KDF - higher protection against crackers, but easier for someone to DoS you. Better approaches: 1) Let the client do expensive KDF (e.g. in JavaScript if it's a web app) and send you only the resulting key. You can then store SHA256(key) instead of KDF(password, salt). 2) Use public keys. This requires some fancy infrastructure like a keychains, keybase.io, PGP software etc, but it is the most secure solution. User saves only his public key on the server and signs authentication token when he wants to get in. Server has absolutely no secret material to leak, while the user has complete control over safety of his keys. This is how SSH works. The reason it is not widely used on the web is because we don't yet have nice infrastructure: nice UI for keychains and protocols for one-click sign-in via crypto signatures. We all should work on this to make it better for our kids ;-)
- mschuster91 13y ago> 1) Let the client do expensive KDF (e.g. in JavaScript if it's a web app) and send you only the resulting key. You can then store SHA256(key) instead of KDF(password, salt). So $hacker has to simply do a rainbow-table attack... no security gained there, except for a vastly bigger key space.
- crusso 13y agoThe reason for his suggestion was to prevent an expensive hashing algo from being a means for creating a DOS, not to make the rainbow table attack any harder... although if you offload an even more expensive operation to the client than you were going to perform on the server, it does make the attack harder.
- jessaustin 13y agoExcept an attacker wouldn't have to perform that expensive operation: she could just iterate over the range of the KDF. Unless there were rate-limiting!
- drdaeman 13y agoJust curious. Isn't this is kind of KDF "abuse"? Because, for storing password information in databases, KDFs aren't used for key derivation (the generated key material is never used as a key for any cipher), but just as slowly performing [salted] hash functions. If so, why say "don't use hash functions and use KDFs" when KDFs are used as hash functions in such cases? Maybe it's better to say something along the "don't use fast hash functions, use slow ones" lines?
- tptacek 13y agoA hash function is a primitive. A KDF is a construction. The construction best used for storing passwords happens to have basically the same goal as the one used to stretch a low-entropy secret into a higher-entropy secret.
- drdaeman 13y agoThanks, that clarifies it. But would it be (more) correct if we'd say "key stretching function" instead of KDF?
- kitd 13y agoI wouldn't say that KDFs used this way is "abuse" any more than hash functions used for secure storage is abuse. It all comes down to what you mean by "hashing". The problem is that the same word "hashing" is widely used (incl by experts) for 2 different things, normal insecure hashing and cryptographic hashing. As he points out, the 2 have different purposes, ie CRC for large files & git blobs, etc for the first, and cryptographically secure storage of small strings for the 2nd. KDFs meet all the requirements of cryptographic hashing. Maybe a new term is needed for the process of cryptographic hashing, like "scrambling", or something that suggests secrecy, rather than just generating a unique value.
- jakobe 13y agoThe biggest issue here is that users are allowed to pick their own passwords in the first place. Sure, you can require them to use passwords with a capital letter and with a number and with a punctuation character, but that will just make them pick "Password1." Better: Use one time passwords sent via SMS. Or send a one-time-login URL via email. If you do have to use a password, just generate a 10 digit numeric code. Sure, some of your customers might complain, but at least you aren't responsible for disclosing people's ebay password when your site gets hacked.
- matthewmacleod 13y agoThat's not "some of your customers might complain" territory, it's "your business failed because nobody signed up" territory. 2FA basically ensures security via a second channel, and it's perfectly possible to store passwords in a secure format. I'm not convinced your ideas there are worth the cost.
- jakobe 13y ago> your business failed because nobody signed up Why? Almost all websites require email confirmation; sending someone a login-URL via email actually has less friction because the password-choosing step is removed! > it's perfectly possible to store passwords in a secure format But it's very hard to do so. Even if you use scrypt, it is very hard to make sure your whole system is actually secure against password leakage. The simple truth is that letting your users choose their own passwords is a liability; and I've decided to avoid this liability.
- the_af 13y agoRe: "Password1". There was an interesting paper, I think by someone from Microsoft, that argued that when users pick silly passwords they are actually being rational. They (the users) informally decide that the pain of overcomplex password schemes just isn't worth it. In other words, remembering passwords or using security-related programs and practices is a high price they have to pay everyday (while we computer literate people often disregard this cost, it is there), while the relatively uncommon security breach is something they often never see. Maybe I'm misrepresenting what the paper states, but my takeaway from it was "don't assume users are dumb when they pick silly passwords. They simply are not willing to use an overcomplex system that for them turns out to be not worth the effort." I just tried to find this paper online but I can't even remember the title :(
- nichochar 13y agoYou don't talk about using a pepper also, combined with a Salt. A pepper is a constant secret you append before hashing, increasing entropy and globally making the guessing much harder. Webapp2 from google has a nice implementation, coming from werkzeug to be found here http://webapp-improved.appspot.com/api/webapp2_extras/security.html http://webapp-improved.appspot.com/api/webapp2_extras/securi...?
- nialo 13y agoThis is deeply pointless. Any attacker that gets the password database is practically guaranteed to get the "pepper" as well. Just Use Bcrypt, pick as high a work factor as you can afford, and worry about something else instead. (if you have a place to keep this extra secret where such an attacker can't get it, why not just put the passwords there?)
- NateDad 13y agoYes, exactly.
- mnw21cam 13y agoAs a counterargument, yes I can think of circumstances where an attacker gets read access to the password database, but not the application configuration (or code, depending) that contains the pepper. Using a pepper is another example of security in depth. It doesn't protect against the situation where your attacker has root access on your server, but it increases the work that an attacker has to do (or the luck that the attacker has to have).
- adwf 13y agoCorrect me if I'm wrong, but I think a large proportion of database hacks are still SQL injection attacks. If you assume that the password handling code is on a webserver and the database is on a separate server, there is no reason to assume that an attacker getting read access to the DB through an injection attack will be able to access a pepper on the webserver. Defense in depth is rarely a bad thing. Especially when it doesn't actually harm the end-user experience.
- eldelshell 13y agoWhat I'm using for my latest project is a not a hash, but using an internal 128 long key to encrypt using PBKDF2WithHmacSHA1 and persisting the result to a blob.
- mcescalante 13y agoAfter reading this, the title is linkbait IMO (the author calls it a "sensationalist title")
- Wohui 13y agoIt is, insultingly so.
- baby 13y agoSo several iterations of md5 + salt is not secure? I'm really wondering how much time it takes to find a password hashed by 5 iterations of md5 + a salt by exhaustive search.
- triangleman83 13y agoHashing a hash is not generally considered secure because you have to assume that if your system was compromised, the hackers will know what methods you used, including the list of salts. If the hash runs quickly then you didn't really cause them any more time/work.
- baby 13y agoThat's right! KDF seems to be better than hashing in the case the server gets compromised.
- danielweber 12y agoAssuming "several iterations" means "a million or more iterations" then you have captured most of what bcrypt gets you. You've broken their rainbow tables and they have to brute-force to find users using "passw0rd". You can tune the "several iterations" the same way you can tune bcrypt. That said, don't roll your own. You probably screwed it up somewhere. Just use the bcrypt library call. Or scrypt to let you roll +2 against GPU attacks.
- TheCoelacanth 12y agoIt's not advisable to use MD5 for anything. It's security is severely compromised. Weaknesses in MD5 have already been exploited to create a fake root CA[1] and a fake Microsoft code-signing certificate[2]. There isn't practical publicly-known preimage attack, but there was a theoretical attack published in 2009[3]. Additionally, MD5 can be calculated far too quickly to use for password hashing. A commodity GPU from 2009 can calculate 200 million MD5 hashes per second [4]. For password hashing you should use something like bcrypt or scrypt which is specifically designed to be computationally expensive. [1] http://www.win.tue.nl/hashclash/rogue-ca/ http://www.win.tue.nl/hashclash/rogue-ca/ [2] http://blogs.technet.com/b/srd/archive/2012/06/06/more-information-about-the-digital-certificates-used-to-sign-the-flame-malware.aspx http://blogs.technet.com/b/srd/archive/2012/06/06/more-infor... [3] http://link.springer.com/chapter/10.1007%2F978-3-642-01001-9_8 http://link.springer.com/chapter/10.1007%2F978-3-642-01001-9... [4] http://bvernoux.free.fr/md5/index.php http://bvernoux.free.fr/md5/index.php
- keithwinstein 13y agoI agree with the basic idea here ("Stop associating 'hashed' with 'secure' when it comes to passwords), and I agree with the recommendation to use scrypt or bcrypt when necessary because "they’re your best option when rolling your own user credential storage." But let's go for a part 3: please try not to store user credentials at all, if you can avoid it! It's not a great idea for every random Web site to create its own notion of identity for every user -- which requires a means of proving that identity, usually a password, and a way for that means to get compromised. When it's feasible, better would be to outsource the job of verifying user credentials to some third party and only accept online cryptographic proofs of identity, whether that's via: * an SSH client keypair (e.g. git push to GitHub) * requiring requests be signed with a PGP keypair (e.g. uploading to Debian/Ubuntu) * Mozilla Persona/BrowserID * a TLS client certificate * Facebook Connect * Google Accounts * OpenID There's another benefit here -- no matter how many times you iterate a KDF, your website is still going to be vulnerable to an online compromise where the badguy just grabs passwords as users log in. (I understand systems like Meteor are nudging sites into using SRP-in-JavaScript, which is great, but in an online compromise that can just change.) And while it may be good to use bcrypt vs. SHA-1, after all it's the users whose interests are ultimately at stake if the password DB is revealed, and yet the users generally have no way of knowing (cryptographically) that any given site really is using bcrypt. That suggests that the security dust is being applied in the wrong place -- the party that actually cares should be able to verify that the right thing is happening. It would have been great if Mozilla had had more resources to stick with Persona (and of course if Facebook and Google could have afforded to endorse it). Unfortunately even sites that are founded by ex-Facebook employees (like Quora) don't actually trust Facebook Connect enough to rely on it -- Quora uses FB Connect to let you "Sign Up with Facebook" but then requires you to establish your own Quora password just in case Facebook screws them over someday. (Then they store the password via unknown means...)
- sillysaurus3 13y agoIf a website's only option for credentialing is Facebook Connect, I won't be using that website. Ditto for Google Accounts. Maybe it's just me. But if many others on HN feel the same way, then that could be relevant for a new startup who wants to gain traction among a core group of initial users. E.g. I never would have used Dropbox or Airbnb if their only option to login was Facebook.
- cocoflunchy 13y agoI see people saying "just use scrypt or bcrypt"! I noticed in Django's admin this line (in the user section, with the default authentication app): algorithm: pbkdf2_sha256 iterations: 12000 salt: 8c8ttQ****** hash: pN+2tq************************************** Am I fine? Is there something more secure? Why isn't Django's default scrypt or bcrypt? And what is pbkdf2_sha256 exactly?
- schrodinger 13y agohttp://en.wikipedia.org/wiki/PBKDF2 http://en.wikipedia.org/wiki/PBKDF2 I think it's fine, although some people believe [sb]crypt to be more secure. I think PBKDF2 is actually the default in ASP.NET now.
- goblin89 13y agoPBKDF2 with SHA256 hashing is default password storage mechanism in Django. Recommending PBKDF2 is one of the things that tptacek criticized “Practical Cryptography With Go” for[0]. Edit: Django has support for bcrypt but it's not the default because of third-party dependencies[1]. [0] https://news.ycombinator.com/item?id=7596280 https://news.ycombinator.com/item?id=7596280 [1] https://docs.djangoproject.com/en/1.7/topics/auth/passwords/ https://docs.djangoproject.com/en/1.7/topics/auth/passwords/
- po 13y agotptacek faulted 'Practical Cryptography With Go' for recommending PBKDF2 over bcrypt and scrypt however this is not what Django is doing. Django chose PBKDF2 of the three primarily because it was easily implemented without pulling in third-party dependencies, which is very helpful for Django's deployment. Given the choice of the three, I think most all Django core developers would say that scrypt or bcrypt would be better but of the three options, PBKDF2 was deemed to be the most acceptable for driving adoption. Before PBKDF2 was added it was using a fast hashing algorithm and had no way to select one so all three were considered improvements and PBKDF2 was considered the 'safest' for adoption, not the optimal one. Note that it is now fairly easy to add bcrypt or scrypt into your django deploy if you choose to. I'd also add that the parent article, talks about PBKDF2 but I am not sure it is using it correctly. It makes no mention of how many rounds it is configured for and I'm not sure what they mean by 'dumb iterations'. It should be able to make it as slow as scrypt or bcrypt or on a single machine benchmark. The advantage of something like scrypt is that it pulls in complexity on memory as well as CPU. Edit For anyone interested in the decision making here, this was the summary ticket on Django password hashing and my summary at the time: https://code.djangoproject.com/ticket/15367 https://code.djangoproject.com/ticket/15367 https://groups.google.com/d/msg/django-developers/ko7V2wDVsdg/N8yYKROKj-MJ https://groups.google.com/d/msg/django-developers/ko7V2wDVsd...
- cordite 13y agoThe recent post "Fairy Tales in password hashing"[0] in regards to scrypt seems somewhat relevant here. [0]: http://vnhacker.blogspot.com/2014/04/fairy-tales-in-password-hashing-with.html http://vnhacker.blogspot.com/2014/04/fairy-tales-in-password...
- skrebbel 13y agoHardly, because it's not about scrypt itself but about how (according to the author) the library's API encourages incorrect usage. A reader of your comment might assume that the article is about some perceived flaw in scrypt itself.
- cordite 13y agoI can see that perspective. I could have made it more clear. I see it as it being more about incorrect usage or application, rather than a fault with scrypt.
- tptacek 12y agoNo, it's not relevant to this discussion at all.
- po 13y agoThis article shows PBKDF2 as being barely any slower than sha2 but makes no mention of how many rounds it is configured for. The note at the end implies that something is misconfigured. I'm not a rubyist, but something is definitely wrong there. PBKDF2 is maybe not the best choice but is certainly safe and better than sha3 if configured correctly. If the author is reading here, it's probably best to take PBKDF2 out of the graph until you get it properly configured. Otherwise, people may choose sha3 as their password hashing function.