Skip to content

Recommended settings

David Bertoldi edited this page May 4, 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 🟢 ≤ 100ms 🟢 🟢 🔴 🔴 🟢
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.

Argon2

In order to be effective, Argon2 should take at least 500-1000ms in order to produce a GPU resistant hash.

Memory

It depends on your system capacity. We can recommend at least 12 kiB.

Iterations

It depends on your system capacity. We can recommend at least 20.

Parallelism

It depends on how many cores have your system. It should be at most the number of available cores multiplied by 2.

Output length

At least 32.

Type

Always use Argon2id

Version

Always use the latest version (19)

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 maxMilliseconds = 500;
int memory = 4096;
int threads = 2;
int outputLength = 128;
Argon2 type = Argon2.ID;

BenchmarkResult<Argon2Function> result = SystemChecker.benchmarkForArgon2(n, memory, threads, outputLength, type);


int iterations = result.getPrototype().getIterations(); // 219
long realElapsed = result.getElapsed() // 468

In this example an Argon2 implementation that hashes a password (Shannon Entropy Index = 4.80) in less than 500 milliseconds must use 219 iterations, 4MB of memory and 2 threads. The real elapsed time for this configuration is 468 milliseconds.

Message Digest

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