9 ms·
Storing Passwords Securely
- DanielRibeiro 14y agoSRP note was very nice: http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol On a more esoteric note: If you are looking to resist quantum algorithms attacks, there are post-quantum algorithms for that[1] (they are computed on normal machines, but the problems behind the crypstosystems are hard to solve even for quantum computers). [1] http://crypto.stackexchange.com/questions/494/what-is-the-post-quantum-cryptography-alternative-to-diffie-hellman http://crypto.stackexchange.com/questions/494/what-is-the-po...
- tptacek 14y agoSRP also has tunable work-factor knobs, although they aren't as explicit as the ones in bcrypt, scrypt, or PBKDF2. But I'd strongly recommend against re-implementing SRP, since it's treacherous to get right.
- shabble 14y agoOf the implementations listed in the WP article, which, if any, are suitable for general purpose use? And what manner of implementation screwups are most likely|hazardous? [With the obvious caveat: Advice not for production use, If you have to ask...]
- tptacek 14y agoIf you're going to use an SRP library, there's an open-source Stanford SRP library (most commercial systems derive from it) which deals with the obvious attacks.
- pbsd 14y agoIf you're worried about quantum computers when thinking some website's security, you're either doing it wrong, or living in the future. Post-quantum is cool alright, but it's not really a thing that implementers need to worry about.
- fein 14y agoI liked the article and it was a nice little afternoon read, but the whole thing could have been condensed to "use bcrypt for passwords". I'm not really sure where to stand on this. On one hand, we have PLENTY of security articles stating the same thing (bcrypt, bcrypt, and just in case you've forgotten... bcrypt), which leads to an observed over saturation of the same subject matter. On the other hand, we have a huge company like LinkedIn that doesn't have the presence of mind to use something other than vanilla SHA-1. Maybe there's just too much lazyness/ stupidity in the world to require a constant barrage of the same security articles every week.
- leftnode 14y agoI imagine things like this is a result of the account management part of LinkedIn being built years ago when we thought plain-jane sha1 was ok to use, and then they just never got around to using bcrypt. Ironically, the algorithm to upgrade to bcrypt is simple. Add a flag to the account table if they've upgraded or not. Next time the user signs in successfully, re-hash their password with bcrypt, toggle the flag, and update the password_hash value in the database.
- pmylund 14y agoI agree there are a ton of articles saying "Use bcrypt." After Coda's post (http://codahale.com/how-to-safely-store-a-password/ http://codahale.com/how-to-safely-store-a-password/) it's almost become a meme. I don't, however, think that the people who say "Use bcrypt!" tend to explain why they say that. I think the reason that this happens so often is that regular developers just don't care. But that's because they don't know why they should care. Given a proper explanation (and an attention span longer than "Squirrel!"), any reasonable developers would (at least, should) care.
- ticks 14y agoIndeed. There's a developer bubble around Hacker News and websites like Stack Overflow, where topics like bcrypt have become second nature. Whereas standard developers, i.e. those that program solely as a job, they don't inhabit these places.
- 14y ago
- trjordan 14y agoOK, so I get the message. Use bcrypt. Don't worry, that's what I'll do in production. On the other hand, if it's so hard to roll your own, can somebody point out the security flaws in the given Python function? Seems pretty straightforward to my untrained eye.
- pmylund 14y agoAlthough it's not that much if you're using a long hash, iterating a hash function causes you to lose entropy. The implementation in the article is basically PBKDF (1). PBKDF2/HMAC avoids this by making an "outer" and "inner" layer.
- rmc 14y agoThe check of hash to input uses == which will shortcircuit and return quicker as you guess the leading digits allowing you to figure out what the hash is. (i.e. a timing attack)
- tptacek 14y agoTry to explain how you would actually conduct that timing attack to see why it isn't one.
- indygreg2 14y agoIf you are going to go through all the effort to do it properly, you might as well use a proper comparison function. If nothing else, it reinforces the knowledge that string comparisons can be part of security (which goes overlooked by many).
- sillysaurus 14y agoI know I won't be able to easily convince anyone of this, but I thought I'd mention... Colin Percival's "scrypt" password hash is: 1) production-ready (and has been for a long time) 2) superior to bcrypt, as it is designed to be expensive in both CPU and memory (hence, scrypt is "memory-hard", whereas bcrypt is not) I don't have time to go into further detail. I encourage you to check it out. It's quite simply "the future of password hashing". (Bcrypt will be defeated by natural advances in multi-core hardware; scrypt won't ever be.) Passwords hashed with scrypt with sufficiently-high strength values (there are 3 tweakable input numbers) are fundamentally impervious to being cracked. I use the word "fundamental" in the literal sense, here; even if you had the resources of a large country, you would not be able to design any hardware (whether it be GPU hardware, custom-designed hardware, or otherwise) which could crack these hashes. Ever. (For sufficiently-small definitions of "ever". At the very least "within your lifetime"; probably far longer.)
- pmylund 14y agoFWIW I included scrypt :) I personally agree that "Use bcrypt." should become "Use scrypt." soon. My main gripe is that there is far less library support for it, at least for now.
- amalcon 14y agoThe usual concern with scrypt is that it has less research behind it. The bcrypt hash function has gone through over twelve years of attempts without being broken in the cryptographic sense. The scrypt hash has only around three years of the same. I would expect that within 5-10 years, scrypt will be the normal suggestion. It really is much better on the fundamentals, so much so that some experts recommend it even in spite of its relative newness. For the moment, though, there are arguments to be made either way.
- tptacek 14y agoYou are going to have a hard time finding a professional cryptographer who will look at scrypt and say that it's risky. These are KDFs, not message authentication codes; they aren't risky constructions. If you have no other choice but to iterate SHA1 many thousands of times, that's still better than what most apps do, and in the grand scheme of things almost "ok". scrypt is fine. If you have a library that supports it, go ahead and use it.
- jharding 14y agoIf you're storing passwords as MD5/SHA hashes, how difficult is it be to switch over to bcrypt? I've never had to do this, but I would imagine it would be somewhat trivial. With all of the password leaks that have happened over the past few years, I'd imagine a good amount of developers are aware that storing passwords as MD5/SHA hashes is somewhat risky, so I can't understand why big websites (LinkedIn) are still doing it.
- ammmir 14y agoif your userbase is fairly active, you could migrate passwords the next time they login (and store a flag indicating the password "version"), since you'd have the plaintext version during authentication time. alternatively, you could bcrypt all hashes now, and anytime you authenticate, making sure to MD5/SHA hash the plaintext password before checking the password using bcrypt. legacy code and especially authentication code that has huge exposure (code path hit during every login and potentially every session auth) is difficult/risky to change once deployed. making things "more secure" has always been a hard sell to management... until a disaster like this happens!
- technomancy 14y agoWe did it on Clojars, the Clojure library source, without much trouble: https://github.com/ato/clojars-web/compare/68872652fc427cc1...efb4e90a9279e8b0b34d8dfeda8deab36d19c808 https://github.com/ato/clojars-web/compare/68872652fc427cc1.... We had a month or two grace period in which anyone logging in would have their password upgraded to bcrypt automatically, then wiped the SHA1s. https://groups.google.com/forum/#!msg/clojure/Xg1I0rgt85s/VfrkiAU9cNEJ https://groups.google.com/forum/#!msg/clojure/Xg1I0rgt85s/Vf...
- njs12345 14y agoCould you use e.g. bcrypt(SHA1(x))? I think that should be OK, and avoids the issues with switching over current users (just take the bcrypt of the currently stored passwords).
- kmfrk 14y agoIn Django, as I recall, you just check for a hashing indicator that's prefixed to the hashed password, and do something like this on a user's log-in: if hashed_password.startswith("sha$"): hashed_password = bcrypt(hashed_password) (or `... = "bc$" + bcrypt(hashed_password)`. However it's done.) Here is the relevant code for django-bcrypt: https://github.com/dwaiter/django-bcrypt/blob/master/django_bcrypt/models.py#L55 https://github.com/dwaiter/django-bcrypt/blob/master/django_.... In your case, you could probably do this: if not hashed_password.startswith("bc$")\ and sha(entered_password) == hashed_password: hashed_password = "bc$" + bcrypt(entered_password) You don't have the prefix identifier, but that's okay; you just roll out an equivalent now instead, so you only have to check the start of the hash string and do the conversion, if it hasn't already been performed. Of course, you have to account for the prefix identifier when validating an entered password against the stored hash. YMMV.
- peeters 14y agoI used to hear some controversy with regards to "stretching." The argument back in the day was, "it's partially security through obscurity, but the danger is that there isn't research to prove that a hash of a hash is cryptographically strong." So is there research that proves that hashing a hash of a hash of a hash (x100000) doesn't result in a smaller range of values than a single hash for SHA algorithms? Is there no such convergence?
- tptacek 14y agoStretching isn't "security through obscurity". It's "security through increasing the attacker's cost by a huge amount while increasing your own cost by a minimal amount". But don't use stretched SHA1. Use bcrypt or scrypt or PBKDF2, all of which explicitly address this particular concern.
- billymillions 14y agobug in the code. return getDigest(password, salt) == digest getDigest returns a tuple
- pmylund 14y agoSo much for white-boarding it. Fixed, thanks.
- mparlane 14y agoAn even better way of securely storing your passwords would be to mix them around on entry to your bcrypt hash function in a unique way that makes it impossible to brute force your leaked password hashes without having access to the code that did them.
- pmylund 14y agoSo something like a HMAC digest generated using a pepper stored in the source code/binary or on disk before passing it to bcrypt/scrypt? :) This only really protects against SQL injection attacks, though/when there is actually a separation between where you store the bcrypt digests and where you store the pepper. (Granted, there are a lot of SQL injection attacks.)
- mparlane 14y agoExactly, most commonly with these things is that the db was dumped which does not imply that the source code was accessed. If the source code was accessed they normally don't need a db dump. (unless it was read-only) The first section of the article IMHO was not needed in regards to a simple hash. Forums have been hashing their passwords with salts for how long now ?
- pmylund 14y agoSure, but I try to not make any assumptions without being boring. I think the goto-link at the beginning works fairly well.
- rokhayakebe 14y agoWhy does everyone need to be an expert in password generation and storing? Would a password as a service would be feasible or even authentication as a service? (And I do not mean FB or Twitter auth)
- apendleton 14y agoEveryone doesn't, and shouldn't. That's why the best practice is not to implement your own hash function, and instead use a third-party library written by an expert. I'm not sure that password-as-a-service would be worth the overhead involved, but password-as-a-library is functionally equivalent from a developer's perspective and is already the norm. The only question, then, is "which library?" which is what this article attempts to address.
- hobbsq 14y agoHAHA... Maybe Linkedin should've used this ;-)
- teyc 14y agoIf you happen to have a web app that stores passwords in clear text or SHA-1 hashed, all is not lost. You can apply further secure hashes to the existing value stored on db and update your authentication validator.
- heretohelp 14y agoOr do the easy thing and perform a chinese fire-drill whenever the user logs in and bump them to the new encryption schema. Or invalidate and send an email.
- fl3tch 14y agoInterestingly, when reddit upgraded to bcrypt, they refused to do this because so many users don't know their passwords and it would lock lots of people out of their accounts forever (remember, reddit doesn't require email addresses to register). http://reddit.com/r/changelog/comments/lj0cb/reddit_change_passwords_are_now_hashed_with_bcrypt/c2t7hoa http://reddit.com/r/changelog/comments/lj0cb/reddit_change_p...
- heretohelp 14y agoGood on them for knowing their users?
- stickfigure 14y agoHow about this: Don't store passwords at all. There are a multitude of sophisticated third-party solutions to authentication. Facebook, Twitter, and Google all offer competent solutions. Don't like those? Use BrowserID. Integrating any of these is actually quite a bit easier than rolling your own solution. It reduces hack risk, provides a better experience for your customers (what was my password again?), and almost certainly will be more reliable than your website.
- pmylund 14y agoOpenID and OAuth really did a lot, but there's just nothing called "don't use passwords." Fingerprint readers suck. Anything biometric that doesn't suck costs too much, and 99% of people don't have them. A good KDF is not bad in comparison to a centralized authentication server considering other factors. Someone, somewhere will be storing user passwords/digests for the foreseeable future. And they will do it incorrectly.
- stickfigure 14y agoSure, but the number of those people should become vanishingly small over time. HN is full of web developers rolling unnecessary username/password solutions. The fact that this is such a hot issue - as opposed to esoterica like TCP frame size - shows that far too many developers are homebrewing solutions rather than outsourcing.
- pmylund 14y agoI agree, but "outsourcing" includes using libraries written by people who know what they're doing. (And not using libraries written by people who know what they're doing, but which are the wrong tools for the job.)
- DanBC2 14y agoFravia used to talk about dongle protection. He was impressed with some of the dongles and the libraries, saying that they were basically secure. But he was not impressed with the ways that companies implemented those dongle protections - sometimes not bothering with any of the advanced features and just using a stupidly simple "dongle present? then run software, otherwise show nag screen" test. Would this be a problem with hashing libraries? Are there any that require very little knowledge for people to implement them correctly?
- deleted 14y ago[deleted]
- uselessuseof 14y agohow about skey and one time passwords
- rorrr 14y ago> MD5, SHA-1, SHA-256, SHA-512, et al, are not "password hashes." By all means use them for message authentication and integrity checking, but not for password authentication. Bullshit. MD5 is just fine, as long as you use the salt. Here, hack this: MD5(password + salt) = "b520542710812f347432232b2a1fba83" salt = "MD5 rules"
- emmett 14y agoMD5 is not fine. MD5 is very very fast[1] and as such it's possible to simply brute force password given relatively modest computing resources. The space of passwords just isn't that big. Use bcrypt or scrypt. Don't make up your own crypto. [1] Crypto benchmarks: http://www.cryptopp.com/benchmarks.html http://www.cryptopp.com/benchmarks.html
- rorrr 14y agoI will believe you when you hack that password.
- deleted 14y ago[deleted]
- ghshephard 14y agoI mean this in the most polite and professional manner possible, please take five minutes and read http://codahale.com/how-to-safely-store-a-password/ http://codahale.com/how-to-safely-store-a-password/ . It will explain why "salts are useless for preventing dictionary attacks or brute force attacks." The entire article is excellent - and every colleague who I've ever pointed at it, has come away nodding their head and seeing the light. The key-takeway (but please, read the entire article) is: "It doesn’t affect how fast an attacker can try a candidate password, given the hash and the salt from your database." Salts only help you from precomputed dictionary attacks ("Rainbow Tables") - but, if someone is brute forcing you, the value of a salt just disappeared.
- romaniv 14y agoSo here is a question that I've asked and received no good answer. Why size of the salt doesn't matter? Wouldn't salt be used in every hash computation? Wouldn't large (megabytes) salt slow down this computation and require more memory to perform it? I'm not advocating the use of large salt as opposed to specialized functions, I'm just curious as to why it doesn't work. The article doesn't explain that.
- pud 14y agoThe article says to give each password its own unique salt and then store the salt (as well as the salted hash) in the database. This seems like a bad idea to me. If a hacker gets access to the salted passwords, in this case he'll probably figure out how to get access to the salts too. I figure if the salt is stored in the code (or a config file...) rather than the database itself, at least it's two different hacks to get (1) the salted hashes, and (2) the salt. Am I misunderstanding?
- Dylan16807 14y agoSalts are not secret. They make you run unique calculations per attacked password and do absolutely nothing else. You might feel like adding a hidden component but it won't noticeably help security and it's not a salt.
- stickfigure 14y agoFurthermore, it's important that the salt be unique per password. If you had a single common salt in your code, then two users with the same password would produce the same hash.
- ashconnor 14y agoThis is only a problem in the sense that once one hash has been cracked the so is the other, however most authentication is done using some user/email attribute also. Usually we fetch user/email, hash password, compare to hash in database - authenticate if match or deny if not.
- lotu 14y agoSo, no changing of email without changing the password then?
- jmaygarden 14y agoNo, just require that the password is entered to change the user's email address. Then a new hash can be generated and stored.
- uzero 14y agoExcellent reading - I spent countless hours researching all this stuff for a project few years back. After my research I came up with very similar protocol than SRP but I find that SRP is a nice POC for both protocols. One thing I didn't find solution for is keyloggers and other similar attacks. If you look at the whole securing your service as a whole, you have to acknowledge the risk of keyloggers also. Now with Flame, Stuxnet and all the other nice things still in the shadows keyloggers can suddenly become also a risk in a large scale.
- SonicSoul 14y agoi've had good experience using KeePass http://keepass.info/ http://keepass.info/ it is open source, and supported by all platforms i use (windows,osx,android,ios) and the interface is pretty well designed. Once local database is open, simply doing ctrl+c on any of the sites copies the password to clipboard for a very limited time. this is still a major pain, especially since you need to protect the safe with a long password and this is particularly painful to type on mobile devices.
- nshankar 14y agoI was just testing with www.Leakedin.com for a possible breakup of my LinkedIn password. I gave my password and said it is leaked. But when I placed a random value, like dsfsfgfdsgsd it said hoorah!, not leaked. So, the onus is on the users, who don't want their passwords to be leaked, rather than depend upon someone to keep it safe.
- deleted 14y ago[deleted]
- pnayak 14y agogreat article!
- Morg 14y agoAuthor: 'There is no reason not to do this for your users.' Yes there is. if every password auth costs you half a billion bucks, you're in trouble. Seriously considering running a hashing routine for more than a second is absolutely unscalable and not smart - you're going to spend infinity computing resources making a super hash of doom for a not-very-important bad quality password like "superMonkey69". Education is still the best answer, when everybody's password is correct horse battery staple, we shall have peace.