-
Notifications
You must be signed in to change notification settings - Fork 26
Recommended settings
In this page you will find advices on which configuration is better.
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 ) |
Not recommended due to its vulnerabilities to GPU/ASIC attacks.
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
Always use a number greater or equals than 10000.
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).
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.
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.
We always recommend at least 10 rounds.
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.
Use it if you are sure that side-channel attacks are not possible in your target system.
Always use a work factor of 214 or greater.
8 should be optimal since cache line sizes haven't changed in the last years.
1 should be optimal for most cases.
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.
Never use it. It is shipped in this library for backward-compatibility.