Skip to content

Recommended settings

David Bertoldi edited this page Feb 18, 2021 · 9 revisions

In this page you will find advices on which configuration is better.

Overview

Algorithm Should I use it? CPU resistant GPU/ASIC resistant FPGA resistant SCA resistant TMTO resistant
Message Digest
PBKDF2
bcrypt 🟡
scrypt ✅ > 100ms 🟡
Argon2 ✅ > 100ms ✅ (d, id) ✅ (i, id)

PBKDF2

Not recommended due to its vulnerabilities to GPU/ASIC attacks.

Algorithm

If your JVM supports it, use SHA-512 or SHA-256 if not present.

In order to check the supported algorithms by your JVM you can use AlgorithmFinder.getAllPBKDF2Variants()

AlgorithmFinder.getAllPBKDF2Variants().forEach(System.out::println);

// PBKDF2WithHmacSHA1
// PBKDF2WithHmacSHA224
// PBKDF2WithHmacSHA256
// PBKDF2WithHmacSHA384
// PBKDF2WithHmacSHA512

Iterations

Always use a number greater or equals than 10000.

Length

At least 256 bytes. If your algorithm produces more bytes, use a greater or equals number (e.g. SHA-512 produces 512 bytes so length should be at least 512).

Responsiveness

If your application requires n milliseconds in order to hash a password and you don't know how many iterations to use, you can use the SystemChecker tool.

long n = 100;
BenchmarkResult<PBKDF2Function> result = SystemChecker.benchmarkPBKDF2(n, Hmac.SHA512, 512);

int numberOfIterations = result.getPrototype().getIterations(); // 48750
long realElapsed = result.getElapsed() // 89

In this example a PBKDF2 implementation that hashes a password (Shannon Entropy Index = 4.80) with SHA-512 in less than 100 milliseconds must have at most 48750 iterations. The real elapsed time for this configuration is 89 milliseconds.

bcrypt

Minor version

Always use minor b.

Version a mis-handles characters with the 8th bit set, x was used by system administrators to mark those bad hashes and y is used for the fixed version of the algorithm. b solves issues with password with more than 255 characters.

Rounds

We always recommend at least 10 rounds.

Responsiveness

If your application requires n milliseconds in order to hash a password and you don't know how many rounds to use, you can use the SystemChecker tool.

long n = 300;
BenchmarkResult<BCryptFunction> result = SystemChecker.benchmarkBcrypt(n);

int rounds = result.getPrototype().getLogarithmicRounds(); // 12
long realElapsed = result.getElapsed() // 247

In this example a bcrypt implementation that hashes a password (Shannon Entropy Index = 4.80) in less than 300 milliseconds must have at most 12 rounds. The real elapsed time for this configuration is 247 milliseconds.

scrypt

Use it if you are sure that side-channel attacks are not possible in your target system.

Work Factor

Always use a work factor of 214 or greater.

Resources

8 should be optimal since cache line sizes haven't changed in the last years.

Parallelisation

1 should be optimal for most cases.

Responsiveness

If your application requires n milliseconds in order to hash a password and you don't know what work factor to use, you can use the SystemChecker tool.

long n = 300;
BenchmarkResult<SCryptFunction> result = SystemChecker.findWorkFactorForSCrypt(n, 8, 1);

int workFactor = result.getPrototype().getWorkFactor(); // 32768
long realElapsed = result.getElapsed() // 218

Once you have the work factor, you can run a similar test for the block size (resource)

long n = 300;
BenchmarkResult<SCryptFunction> result = SystemChecker.findResourcesForSCrypt(n, 32768, 1);

int resources = result.getPrototype().getResources(); // 9
long realElapsed = result.getElapsed() // 240

In this example a scrypt implementation that hashes a password (Shannon Entropy Index = 4.80) in less than 300 milliseconds must have a work factor of 32768 and a resources less or equals to 9. The real elapsed time for this configuration is 240 milliseconds.

Message Digest

Never use it. It is shipped in this library for backward-compatibility.

Password4j documentation

Clone this wiki locally