103

There are many questions about picking a hash function, including How to securely hash passwords? or Are there more modern password hashing methods than bcrypt and scrypt?, with very detailed answers, but most of them date quite a bit.

The consensus seemed to be that:

  • bcrypt is a good choice
  • scrypt should be a better choice, but, at the time, it was still a bit new, so one should have to wait to see if it stands the test of time

Argon2 is now the winner of the Password Hashing Competition, but it is definitely still quite new, so the same arguments that applied to scrypt at the time probably apply to it now.

Questions:

  • Is bcrypt still a good choice?
  • Is scrypt now a good choice?
  • Is Argon2 already a good choice?

Basically, today, for an average system with passwords, which password hashing function should one prefer? For those functions that have parameters, what should they be?

Edit

Note that even though the question is a near duplicate of How to securely hash passwords?, as stated above, most answers to that question date back to 2010-2013, with the most recent relevant updates dating back from 2016. Things have obviously changed since then, and what I am looking for is an update to those excellent answers. Feel free to answer with an update in that question and close this one if you think it makes more sense, but please don't just close this one without an up-to-date answer either here or there.

Zakk
  • 103
  • 4
jcaron
  • 3,365
  • 2
  • 15
  • 22
  • 4
    Possible duplicate of [How to securely hash passwords?](https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords) – forest Sep 10 '18 at 02:25
  • 10
    Briefly, Argon2 is recommended now days with the highest parameters you can tolerate. Scrypt is also secure but is less flexible, and bcrypt is better than nothing, but not particularly memory-hard nowadays. – forest Sep 10 '18 at 02:27
  • Regarding your edit, the relevant answers still apply, with the exception that Argon2 is now recommended over scrypt due to its flexibility (as a few answer updates point out). – forest Sep 10 '18 at 08:13
  • 2
    @forest The "exception" is what I'm actually looking after. Is it really already recommended? Do others think it has stood the test of time? It's still quite recent. Also in most of those answers scrypt itself was still considered as "quite new". I guess it's not longer the case. What about the current "viable" parameters? – jcaron Sep 10 '18 at 08:15
  • 1
    Yes, it has still stood the test of time. Not to mention, it is standardized. As for "viable parameters", that really depends on you. No matter how things pan out, the answer is always going to be "as high as you can tolerate". – forest Sep 10 '18 at 08:18
  • 1
    @forest bcrypt just being “better than nothing” is quite an understatement, though. Those three algorithms all pretty secure, and unless your attacker is extremely motivated and has a lot of resources, they will all work great. You could even argue that Argon2, and even more so scrypt, still need more analysis before you can safely argue for them to be superior to bcrypt. – caw Sep 17 '18 at 02:13
  • @jcaron Cryptographic hash functions and password hashing functions are not fashion. So you don’t have to ask for the trendy algorithm of the year each time. But sure, getting up to date and asking if any new research has been published is a good idea, nevertheless. – caw Sep 17 '18 at 02:15
  • @caw I believe you can definitively prove that Argon2 is better than bcrypt since any weakness would be in a space-time trade-off. Nowadays, bcrypt is not much better than PBKDF2. – forest Sep 17 '18 at 03:11
  • I'd recommend [yescrypt](https://www.openwall.com/yescrypt/) these days. – Frank Denis Nov 27 '19 at 19:34

1 Answers1

85

As of 2021, Argon2id is the preferred password storage function. You should ideally use a wrapper such as libsodium, which offers password storage functions based on Argon2id and automatically selects sensible hardness factors.

THE ADVICE BELOW WAS WRITTEN IN 2018.


I do not recommend bcrypt for new designs where the input value is human-generated token (e.g. a password) and offline cracking is in the threat model. The lack of memory-hardness is a serious problem when you consider how powerful commodity hardware is these days. While the lack of any major bcrypt-based cryptocurrencies has not attracted FPGA or ASIC mining implementations for the algorithm, there has still been some interest in attacking bcrypt using hybrid ARM/FPGA SoCs, such as in this paper from 2014. Ultimately, the lack of memory-hardness is a significant problem for modern designs.

scrypt has memory hardness as part of its design, but it has some shortfalls. For a start, there are quite a few scrypt-based cryptocurrencies and this has attracted quite a market for commodity FPGA and ASIC mining solutions that could be repurposed for cracking. Furthermore, scrypt's memory-hardness and iteration count are both tied to a single scalar cost factor. This makes it difficult to tailor scrypt to your own threat model. I recommend scrypt where it is the easiest option for password storage in the language or framework you're using, for example if it is already an inbuilt option for protecting user passwords.

Ultimately, I always recommend Argon2 as the preferred choice, for a few reasons:

  1. It has been around for a while now - it won the PHC in 2015. There have been quite a few papers studying Argon2's security proofs, and many more studying potential ways to accelerate the algorithm on dedicated hardware. So far it has withstood scrutiny very well.
  2. There are open source implementations and bindings for C, Erlang, Go, Haskell, JavaScript, Java, Lua, OCaml, Python, R, Ruby, Rust, C# (both Framework and Core), Perl, and Swift.
  3. Argon2 is built around the AES cipher, and most modern x86_64 and ARMv8 processors implement an AES instruction set extension. This helps close the performance gap between the intended system and a dedicated cracking system. (EDIT, Feb 2019: It seems that newer versions of Argon2 may not be compatible with the AES implementation in hardware extensions. See comments for discussion around this)
  4. Argon2 is particularly resistant to ranking tradeoff attacks beyond a memory fraction of one third, making it much more difficult to accelerate cheaply on FPGAs. This is because FPGA-based cracking solutions are mostly limited by memory bandwidth, and with Argon2's design the attacker must swallow a great increase in computational time in order to reduce memory bandwidth requirements, thus making the tradeoff inefficient. You can read more about this in section 5.1 of the Argon2 paper, with information on scrypt available for comparison in table 6 (under section 5) of the paper "Tradeoff Cryptanalysis of Memory-Hard Functions".
  5. Memory-hardness and CPU-hardness parameters are separately configurable, along with a parallelism factor. This allows you to better tailor the security bound to your use-case, such as a server with moderate CPU power and a large amount of RAM.

As you noted, the parameters you choose are important. scrypt doesn't give you much choice, so I recommend picking a cost factor based on time (e.g. 1500ms of processing) in that case.

For Argon2 you have more choices than just parameters. There are in fact three different implementations of Argon2, known as Argon2d, Argon2i, and Argon2id. The first one, Argon2d, is most computationally expensive and resistant to acceleration by GPUs, FPGAs, and ASICs with limited memory bandwidth. However, since the memory accesses of Argon2d are dependent on the password, side-channel attacks that leak information about memory accesses may reveal the password. Argon2i, as its suffix suggests, selects memory addresses independently of the password. This reduces its resistance to GPU cracking, but eliminates the side-channel attack. Argon2id is a hybrid approach wherein the first pass uses the Argon2i (independent) approach, and subsequent passes use the Argon2d (dependent) approach.

Wherever possible you should use an Argon2id implementation. However, this is not always available. For a scenario in which you are protecting passwords on a server and your threat model deems memory access side-channel attacks to be very unlikely (this is most of the time in my experience) you may use Argon2d. If memory access side-channel attacks are deemed to be a potential risk, e.g. in a multi-tenant system where untrusted or less-trusted users run code on the same system that does the Argon2 hashing, then Argon2i may be the better choice.

In short: use Argon2id if you can, use Argon2d in almost every other case, consider Argon2i if you really do need memory side-channel attack resistance.

For the parameters, the only hard rules are for Argon2i, which must be treated specially due to its comparative weakness to the other options. Specifically, the number of iterations must be 10 or more, due to a practical tradeoff attack on Argon2i.

You should tweak the parameters to your own use-case and performance requirements, but I believe the following are acceptable defaults for Argon2id and Argon2d:

  • 512MB of memory
  • 8 iterations
  • Parallelism factor of 8

The speed of this depends on your processor, but I achieved approximately 2000ms on my system.

For Argon2i you must increase the number of iterations to a minimum of 10, which may require you to decrease the memory factor for performance reasons. This is another reason to try to avoid Argon2i unless you absolutely require its resistance to memory access side-channels.

Polynomial
  • 132,208
  • 43
  • 298
  • 379
  • Great link to source implementations for platforms that do not supply Argon2! – zaph Nov 13 '18 at 07:44
  • Just a quick comment, ASICs built for crypto will most likely not help crack any passwords. ASICs like the ones built for crypto mining don't just hash, but the compute an entire block in hardware. This won't help cracking passwords with the same hash. – MikeSchem Nov 13 '18 at 08:53
  • 1
    @MikeSchem While they won't on their own, an adversary with sufficient resources can simply reuse the existing silicon IP to build something that does. It's a massive cost reduction over a brand new design. – Polynomial Nov 13 '18 at 09:14
  • Do you have a link to anywhere with more information on item 3? I want to believe it, but I see no sign of the actual implementation using AES instructions. The argon2 submission document has this to say "We stress that this approach is not possible with dedicated AES instructions. Even though they are very fast, they apply only to the 128-bit block, and we still have to diffuse its content across other blocks" However it isn't clear to me that this means dedicated AES instructions can't be used as opposed to applying to a specific part of the algorithm. – Malcolm MacLeod Feb 23 '19 at 09:11
  • 1
    @MalcolmMacLeod My understanding is that some of the AES-NI instructions are incompatible with Argon2 because of some implementation specifics, whereas other parts of the AES-NI instruction set are still useful, but I agree that the documentation isn't clear on this. I'd have to ask the authors, or someone who has actually implemented it. – Polynomial Feb 23 '19 at 17:26
  • 1
    From further reading I've come to the understanding that earlier versions of argon2 during the competition could make use of AES-NI but that after it was modified this is no longer the case. It is possible I'm mistaken but that is what it seems like to me. Perhaps if we can't get a 100% clarification at least update the answer to state that this is not 100% clear so as to avoid anyone getting the wrong idea without further research. – Malcolm MacLeod Feb 27 '19 at 21:54
  • @MalcolmMacLeod I added a note to the answer. Thanks for the insight. – Polynomial Feb 27 '19 at 22:01
  • 1
    How old is Argon2? (How long have experts been trying to crack it?) – jpmc26 Feb 28 '19 at 10:56
  • 2
    @jpmc26 The original version was 2015. It was updated as late as March 2017. However it is worth noting that Argon2 is built on primitives and design structures that have been around much longer, so some of the cryptoanalytical work was transferable from earlier efforts on other algorithms. The security analysis section of the Argon2 paper linked above is also quite nicely written; none of the analyses rely upon unusual proofs or questionable assumptions. – Polynomial Mar 03 '19 at 17:18
  • Argon2 never used AES. That would be "Argon". (Fitting with the tradition in the world of computing of confusing and trolly names, the newest set of algorithms in the argon family is called "Argon2 v 1.3") They went with reduced round Blake2 because it outperformed reduced-round-AES-based constructions. Later they used a tweaked version (blamka) which further closed the performance gap without seriously impacting software performance. – Future Security Aug 26 '19 at 01:43
  • I think future Intel CPUs will have VAES instructions. (Like AES-NI but SIMD.) That might be something a future version of Argon(2) could take advantage of. I don't know if that would make the new algorithms name "Argon3" or "Argon2 v 1.4". It may or may not be more efficient than blamka, so it might not even help to change the algorithm for new hardware. Either way, people should use the newest version of Argon(2). It's currently the best option, superior to bcrypt, scrypt, and PBKDF2. There being a slightly better option in the future doesn't justify using something inferior in the present. – Future Security Aug 26 '19 at 02:01