4 ms·
Please do not use the SHA family of hashes to store passwords. They are designed to be fast. This makes brute forcing them relatively easy. There are hashes des
by JulianMorrison 6y ago
Please do not use the SHA family of hashes to store passwords. They are designed to be fast. This makes brute forcing them relatively easy. There are hashes designed for passwords that are not fast.
- EGreg 6y agoCan you saw which? Blowfish?
- valauran 6y agoUse argon2 or scrypt for password hashing. PBKDF2 or bcrypt are also acceptable, but prefer the first two in new systems. Make sure to use appropriate complexity factors. A good starting point when trying to decide what crypto algorithm to use is https://latacora.micro.blog/2018/04/03/cryptographic-right-answers.html https://latacora.micro.blog/2018/04/03/cryptographic-right-a...
- JulianMorrison 6y agoI absolutely love that right answers document. Thank you.
- teddyh 6y agoPeople used to say “Just use bcrypt.”, but this might have changed since. A cursory look seems to indicate that Argon2 is the current preferred choice.
- tptacek 6y agobcrypt is fine. It has held up quite well. Really, when picking among the mainstream password hashes, just throw a dart if you need to.
- __s 6y agopbkdf2: https://en.wikipedia.org/wiki/PBKDF2 https://en.wikipedia.org/wiki/PBKDF2 Your standard crypto library probably implements it (Rfc2898DeriveBytes for .NET). Under the covers you should tell it to use SHA512. If you can choose something better go ahead, but this is often good enough
- deleted 6y ago[deleted]
- johnisgood 6y agoYes, it is called stretching. Cryptographic hash functions are typically designed to be computed quickly, so it is possible to try guessed passwords at high rates. You could try billions possible passwords each second. This is why we have password hash functions that perform key stretching, such as PBKDF2, scrypt, or Argon2. They increase the time (and sometimes even memory) required to perform brute-force attacks on stored password hash digests. Use a large (256-bit is fine) random salt value. All the salts are random values (note: they do not have to be a secret), so each user will use a different salt value, and now the attacker has to compute the stretching function once for each password combination, rather than once for each password, and this is a lot more work for the attacker. If you only hash with a salt, it still leaves passwords exposed to brute-force attacks and dictionary attacks that they can easily run on GPUs. Key stretching is important! This is why we have dedicated password hashing functions that are slow enough to mitigate brute-force and dictionary attacks. TL;DR: salting and stretching on passwords, along with password hash functions (slow password hashing functions: PBKDF2, bcrypt, scrypt, Argon2, Balloon and some recent modes of Unix crypt)! Do not use fast cryptographic hash functions on passwords, as it defeats the purpose of stretching. Salting is not enough.
- JulianMorrison 6y agoDo not, ideally, roll your own out of anything.
- deleted 6y ago[deleted]
- rlpb 6y agoFurther, a hash is the wrong primitive to use to store passwords. Just as you wouldn't attempt to invent a cryptographic hash function yourself. The correct primitive to use is a key derivation function. Examples are PBKDF2, bcrypt, scrypt and Argon2.
- SAI_Peregrinus 6y agobcrypt is NOT a key derivation function. It IS a "password hashing function". PBKDF2, Argon2, and scrypt are both.
- dehrmann 6y agoAs others have said, use scrypt, but... PBKDF2, obviously a less marketable name than scrypt, was a pretty standard tool for dealing with fast hash functions. What turned out to be a bigger problem than speed is memory use. Now that we have widespread GPUs, it's a lot easier to parallelize password cracking, and most cryptographic hash functions use negligible memory, so it parallelizes very well. scrypt also improves this. I actually saw scrypt take down a website. It got attacked with brute-force password attempts (<100k, so it wasn't a serious attack), and the scrypt calls exhausted the CPU, essentially doing a DoS attack. We ended up wrapping the call in a semaphore to prevent this. You don't normally think about it, but login might be the most expensive operation your webserver does.
- AnthonyMouse 6y agoI've never really loved this advice. If people use weak passwords, the hash algorithm doesn't matter, they're going to get cracked. If you use strong passwords, the hash algorithm doesn't matter, they're not going to get cracked. This sort of thing only matters for medium passwords. And can be avoided by requiring strong passwords. It also does very little against precomputation attacks (e.g. rainbow tables), because it makes it take longer to compute the tables but it's still efficient to use them. Meanwhile it adds a user-perceptible amount of latency to logging in, because the hash algorithm is so slow. That causes users to take steps to avoid it, e.g. by staying logged in when they don't need to or preventing their machine from locking, which reduces security.
- deleted 6y ago[deleted]
- __s 6y agoNot sure what you're suggesting, but I'll try to give benefit of the doubt & guess you advocate for giving users randomly generated 64 character hex strings & password resets only give them a newly generated password At that point it may be suitable to store the password as plaintext, though a layer of hashing could be suitable to slow down an attack from authenticating in case they get read access to the database
- saurik 6y agoI mean, the "reality" is that if a user uses the same password across multiple sites then they are almost certainly screwed as the entire premise that we are going to guilt all the big websites into storing hashed passwords doesn't work for the long tail of websites that each had a high likelihood of being run by a scammer anyway. Users really just need to not use the same password across multiple websites, and that password needs to be high entropy. The recommendation of "hash your stored passwords" prevents you from being part of the problem, but it is a solution to the wrong problem and fails to protect either the user or the website from getting hacked: the recommendation--at least and certainly if assuming you insist on implementing login with the classic "user will later send a plain text copy of their secret to the server each time they log in, which the server will (somehow) verify"--absolutely should include "don't let the user generate their password", as anything else does a disservice to the user and doesn't actually help the website. If the user is sane, they won't care if you generate the password. If the user isn't sane, then either 1) they are using some kind of weird deterministic scheme to generate passwords for all websites (which is frankly not optimal); 2) they are intending to use their password on another, less secure website (and so should be prevented from using that same password on your website); or 3) their password is something stupid (like their mother's maiden name, concatenated with their date of birth... but they change the i's to exclamation points to get around the symbol requirement).
- dwheeler 6y agoI completely agree. If you're directly using a SHA hash for password storage, even with salt, you're doing it so incompetently that you should probably be fined. At the very least use a well-studied iterated salted hash algorithm for storing passwords (if you must authorize an incoming request later). That is a minimum bar. I generally recommend argon2. Reasonable alternatives are bcrypt, scrypt, and PBKDF2. PBKDF2 is weak against hardware, but it's still better than using a hash directly. I teach a class on developing secure software, and students have to do a final project. I take off points if they directly use SHA for password storage; that's just not acceptable.