So you’ve decided to store hashed versions of your application user’s passwords, great start! You’ve done a bit of reading and decided you want to use a specialised password hashing algorithm. You implement it with the default security configuration in your favourite cryptography library, and you’re all set right?
Many developers don’t take the final step to investigate the default configuration when implementing specialised password based hashing algorithms. However, the default configuration often does not provide the level of security required for current implementation. These algorithms are utilised for password hashing because they’re slow, this slows offline brute forcing attacks in an attempt to stop them from being successful. The “slowness” is described as the algorithm’s work factor. This work factor can be tuned to increase the amount of processing power required to perform the algorithm, thus increasing the amount of time that would be required to crack the password hash. The observation from Moore’s Law trends towards a doubling of computing power every 18 months. This means that if it takes 24 hours to brute force a hash today, in 18 months time (on new hardware) this same attack should take approximately 12 hours to perform. Many password hashing algorithms are available or recommended, each with their strengths and weaknesses which will be discussed. Even with default configuration, these algorithms are better than using nothing. However, due to Moore’s Law, to maintain the same level of security the work factor needs to be increased to maintain this security at currently available processing power.
This article attempts to cover some detail of currently popular password hashing algorithms and provide a set of data from an experiment for establishing current and future work factor recommendations. Finally, a simple JavaScript calculator at the bottom of this article allows calculations for current recommended work factors.
Password-Based Key Derivation Function 2 (PBKDF2)
PBKDF2, the successor to PBKDF1 utilises an input password, along with a salt and repeats a hashing algorithm several times to produce a key. Being a key derivation function, it performs key stretching and can produce outputs of specified length. Advantages of PBKDF2 include its ease of use in any .Net application and its flexibility, as no hashing algorithm is defined. The disadvantages have to do with the flexibility, as weak hashing algorithms can be utilised, and its lack of algorithm design against specialised cracking hardware such as GPUs, FPGAs, or ASICs. Several attacks against PBKDF2 can be found, an example from A. Visconti et. al in 2015 is available in the references. However, PBKDF2 when correctly implemented is still considered secure.
BCrypt
BCrypt is a password hashing algorithm based on the Blowfish block cipher. Much like PBKDF2 it requires a salt, password (your input), and repeats a hashing algorithm several times. Where BCrypt differs, is that it is based on the block cipher Blowfish. The advantages of BCrypt are that due to its age, it is well studied and understood and has a large variety of libraries in many languages that allow easy integration into any application. Along with PBKDF2, BCrypt was never designed with resistance against specialised cracking hardware such as GPUs, FPGAs, or ASICs.
SCrypt
SCrypt is another password-based key derivation function, however the algorithm design had specialised hardware resistance in mind. SCrypt requires a salt, password, blocksize, CPU cost factor, parallelization factor, and output key length. The hardware resistance comes from the ability to increase the parallelization and memory requirements of the algorithm, thus reducing the effectiveness of specialised hardware. However, due to the popularity in SCrypt based cryptocurrency, increased scrutiny and improvements in technology have lead to specialised hardware that overcomes the generalised cost increases of the SCrypt algorithm. See the Innosilicon A6 LTCMaster, which implements SCrypt on ASICs. This has lead to some recommendations against SCrypt for password hashing.
Argon2
Argon2 is yet another password-based key derivation function, this algorithm was selected as the winner of the Password Hashing Competition in July 2015. Argon2 does provide three modes of operation; Argon2d, Argon2i, and Argon2id. However, only Argon2id should be used as several issues have been found with the other two versions. Argon2 provides resistance against specialised hardware attacks by allowing the tuning of the parallelism and algorithm memory requirement. The Argon2d (of which Argon2id performs some part of) resists specialised hardware attacks further by accessing the memory array used during the algorithm in a dependent order, thus negating any time-memory trade-offs. The negative of Argon2 currently is that the algorithm is new, and very little cryptanalysis has been published.
Experiment
As outlined, the idea behind the experiment is to use a few systems of different ages to establish a baseline work factor for each algorithm. The following processors on various systems were utilised:
- Core i7 7700K
- Launch Date Q1'17
- Core i5 5300U
- Launch Date Q1'15
- Xeon E3 1275v3
- Launch Date Q2'13
For some algorithms, such as SCrypt and Argon2 the default parallelism and memory usage was used. This needs to be taken into account when implementing as these configurations are hardware dependent. For the experiment it’s expected the minimum level of security for a password hashing algorithm will take 100 milliseconds, where high security will take approximately 1000 milliseconds (or 1 second). Each algorithm is executed with a random string and an increasing work factor. This is repeated ten times and averaged to obtain the time taken for that work factor. The process of increasing the work factor is repeated until the algorithm takes longer than 2 seconds. A link to the source code is available on GitHub here: https://github.com/cptwin/Password-Hashing-Algorithm-Benchmark-Tool-PHABT-. The full raw results of this experiment are also available in the GitHub repository.
Results and Recommendations
As of the 15th of January 2019 the minimum and recommended work factor for each password hashing algorithm is listed in the table below.
| Algorithm | Minimum Work Factor | Recommended Work Factor |
|---|---|---|
| BCrypt | 11 | 14 |
| SCrypt | 16384 | 174762 |
| PBKDF2 | 26667 | 373333 |
| Argon2 | 533 | 4267 |
Utilising these base work factors, future work factors can be calculated using the following formulas:
Bcrypt
(BCrypt Doubling Constant equals N+1)
- M = (Number of months since 15/01/2019)
- B = (Base Security Value)
- 18 = (Moore’s Law Constant)

PBKDF2, SCrypt, and Argon2
(Doubling Constant equals N*2)
- M = (Number of months since 15/01/2019)
- B = (Base Security Value)
- 18 = (Moore’s Law Constant)

Conclusion
The concept of a configurable work factor should be shifted from an algorithmic one to a time based one for developers. Instead, developers should be concentrating on how long of a delay their application or users can handle. This would lead to password hashing libraries that scale the work factor using the presented work factor calculations, to maintain security over time.
JavaScript Calculator
References
A. Visconti et. al, 2015