7 ms·
A lot of people in the comments are wondering about using SHA-2 vs Blake3 for password hashing. The answer is, neither of these is suitable by itself for passwo
by nneonneo 7y ago
A lot of people in the comments are wondering about using SHA-2 vs Blake3 for password hashing. The answer is, neither of these is suitable by itself for password hashing. Sadly there’s still a lot of advice on the internet (and, sadly, real systems) which do things like store md5(password) in a database and call it a day.
Blake2/3, SHA-2/3, and other cryptographic hash functions are meant to be fast, while also effectively guaranteeing no collisions or any way of reversing the hash (pre-image attack). This makes them ideal for stuff like checking file integrity, message authentication, inputs for cryptographic signatures and the like. But since they’re meant to be fast, they’re very poor choices for hashing low-entropy data such as passwords - attackers can test vast numbers of passwords (even if you salt!!) on GPU hardware.
For low-entropy data, you want a hash function that is slow and hard to parallelize. Use a specialized password hashing algorithm like bcrypt, scrypt or Argon2, and tune it so it’s slow enough without impacting overall usability (e.g. takes 50ms on your server). These algorithms are resistant to parallelization, so attackers will only be able to test a small number of passwords per second. This slows attackers down and can prevent them from recovering passwords that might be recoverable if stored using SHA-2, etc.
- nolok 7y ago> tune it so it’s slow enough without impacting overall usability (e.g. takes 50ms on your server) I want to insist that this is a very important part. If you are 99.9% of applications or websites out there, the only time you need to run that hash is at registration, login and password change. All of these case will be fine if it's a bit slow. Don't lowball it. Also informationally I would like to add that as part of their "meant to be slow" job, algorithm like bcrypt are built in a way that makes it extremely hard if not impossible to run on cheap massively parallelized hardware (eg: CUDA on GPU).
- kragen 7y agoAlso you can do the stretching in the browser client (“server relief”) without losing security. Historically this would have meant a big performance penalty (and thus an advantage for attackers, who don't need to use your code) but JS and wasm are fast enough now that the price is fairly low.
- tgb 7y agoCan you elaborate? This doesn't sound right to me but I don't know much about this.
- deleted 7y ago[deleted]
- kragen 7y agoIt is indeed surprising; it took me a long time to be sure it was safe. Google “server relief”.
- jaytaylor 7y agoInteresting read: http://ithare.com/client-plus-server-password-hashing-as-a-potential-way-to-improve-security-against-brute-force-attacks-without-overloading-server/ http://ithare.com/client-plus-server-password-hashing-as-a-p...
- pitaj 7y agoThat is pretty interesting, but doesn't actually offer up a solution that provides server relief, unless I missed something. In every case they still require that HSrv be a slow hash function.
- jaytaylor 7y agoMy take away was that the server relief comes from reducing the ability of clients to trigger disproportionate amounts of server resource consumption.
- nneonneo 7y agoI don’t see how that follows. If HSrv is expensive or slow, a malicious client could just submit nonsense hashes that only look like they might have come from HCli - the server shouldn’t be able to tell the difference. Requiring client-side JavaScript for your login system seems fraught. I would much rather have an approach that does server side hashing exclusively, but gates it behind some kind of DDoS protection or rate-limiting.
- CalmStorm 7y agoBut you also need to be careful. The slow password hashing can be exploited for Denial of Service attack. You may want to rate-limit the APIs that use the hash algorithm.
- littlestymaar 7y agoThis is a good time to ask for a question I have always wondered about these slow hash functions: are they slow because they are computationally intensive or is it that they have other tricks that makes them slow without costing too much load on your server (like needing RAM access, syscalls or anything that add latency but not much CPU load). If it's the former, isn't it a good DOS target, making your server busy hashing random crap and unable to process other requests?
- dpc_pw 7y agoThey are computationally slow, no tricks. The purpose is to prevent attackers from calculating the plain passwords if they actually got access to the content of your DB. They are not that slow (let's say less than a second to calculate) - fast enough for your user to not notice , slow enough so that attacker can't do gazillion tries per second with their GPU or something. As per DOS: rate limit per ip and account, and it's not an issue.
- phiresky 7y ago> They are computationally slow, no tricks They have to and do use tricks, they aren't just slow. You could trivially make sha256 slow by just applying it a million times (that's not even parallelizable as well), but scrypt et al improve on that by making the algorithm also require a lot of RAM, use complex instructions (hard to recreate on a GPU or FPGA) and so on. It's really hard to do very well, look at cryptocurrencies trying to be ASIC resistant: They want every normal person to be able to mine it, and don't want companies to be able to build a machine that can eclipse the mining power of everyone which means centralization.
- wongarsu 7y agoThey are computationally expensive. scrypt and Argon2 also depend on RAM access for their slowness, since that's much harder to parallelize (compute is easier to scale than RAM bandwidth). When your CPU can do hyperthreading that property might help recover some of that execution time. It is a good DOS target, you should definitely rate limit logins to mitigate that. Other strategies are requiring captchas for login or letting the client execute the hash function and just doing a simple (fixed time) comparison on the server side.
- bigcohoneypot 7y agoI get md5 is pretty weak now, but what's wrong with sha-256 and a salt?
- bawolff 7y agoThe md5 weakness (that everyone talks about) is about collision resistance, which isn't relavent to password hashing. Generally you want slow, high cpu & memory hash functions for password hashing. This is the opposite of what md5/sha/blake aim for, as they want to be fast as possible. A fast hash allows the attacker to make many guesses very quickly (i think you can get something like 2 billion sha256 hashes a second with high end gpus). A slow hash makes it harder for the attacker to take lots of guesses (adding high mem usage helps protect against using alternate architectures like fpgas to speed things up). Anyways, for passwords use something like argon2.
- nneonneo 7y agoThe Bitcoin network can perform some 10^20 SHA-256 hashes per second. That’s one 11-character upper/lowercase alphanumeric password PER SECOND. A practical password cracking rig can probably do upwards of 10^11 hashes per second. The same rig can only do 10^5 bcrypt hashes per second.
- basilgohar 7y agoSalting only protects against rainbow tables, but does next to nothing against brute force attacks because the salt is usually stored adjacent or even as part of the stored password hash.
- stevefan1999 7y agoAnd we should all use bcrpyt to hash password. We all should have had it long long time ago, and people are still rolling out their own password hashing with salting mechanism. Biggest facepalm in the industry in my eyes.
- blattimwind 7y agonot processing plaintext passwords on your server >> argon > scrypt > bcrypt > pbkdf2 >>> any hash
- CaptainMarvel 7y agoThere is an algorithm to authenticate without sharing the plaintext password from client to server, nor server to client - SRP. I know Apple uses it.
- ris 7y agoUnless any of your users ever try and use a >72 character password.
- masklinn 7y agoTBF that's super easy to work around: just prehash the key. In fact, an other risk of bcrypt is that any nul byte will truncate the key, so you probably want to hash the password with something else (SHA384 or SHA512/256 for instance) then base64/base85-encode it before passing it to bcrypt.
- throwaway838475 7y agoThe correct term is PBKDF. And more succinctly: crypto hash fn != authenticated hash fn (like HMAC constructions) != PBKDF
- masklinn 7y agoThe correct term is KDF, PBKDF is a specific KDF algorithm.
- SkyMarshal 7y ago>For low-entropy data, you want a hash function that is slow and hard to parallelize. Use a specialized password hashing algorithm like bcrypt, scrypt or Argon2, and tune it so it’s slow enough without impacting overall usability (e.g. takes 50ms on your server). For most of the 2010s I've been under the impression that password hashing was a solved problem and that this is the solution. And yet I still see comments online saying to hash passwords with a salt + 10,000 rounds of PBKDF2. Why bother when you can just b/scrypt it? Is there still some benefit of the former over the latter?
- aaronmdjones 7y agoThere are two principal benefits of sticking with PBKDF2: 1) It's a NIST standard. This may be necessary in some environments, typically just to check a box. (Yeah, I know...) 2) It's necessary for SCRAM (RFCs 5802, 7677), which is a much better login method based on passwords. This is applicable if your system uses GSS-API or SASL (e.g. dovecot IMAP logins). If neither applies, my advice is to migrate to Argon2.
- masklinn 7y agoAlso PBKDF2 is really easy to implement if you have a cryptographic hash (even more so with a ready-made HMAC), which is useful if you can't or don't want to pull in dependencies.
- deleted 7y ago[deleted]
- masklinn 7y agoThe official Blake3 site / repo actually covers this itself: > NOTE: BLAKE3 is not a password hashing algorithm, because it's designed to be fast, whereas password hashing should not be fast. If you hash passwords to store the hashes or if you derive keys from passwords, we recommend Argon2.
- mekster 7y agoArgon2 is a recent entry which won the password hashing competition in 2015 and is slowly getting included in recent versions of languages like PHP 7.2 as an alternative to bcrypt. https://password-hashing.net/ https://password-hashing.net/ As stated in the parent, integrity check hashing (should be fast) and password hashing (should be slow) are very different things and should not be mixed to use wrong implementations. As bcrypt and argon2 both have specific prefixes, you can still keep bcrypt hashes and verifier can work on both (assuming it supports argon2) while using argon2 for newer entries stored in a database. (Preferably update the old bcrypt into argon2 on next login or something.)