JEP draft: Argon2 Password Hashing Algorithm
| Owner | Artur Barashev |
| Type | Feature |
| Scope | SE |
| Status | Draft |
| Component | security-libs / javax.crypto |
| Effort | M |
| Duration | M |
| Relates to | JEP 510: Key Derivation Function API |
| Created | 2026/02/03 15:26 |
| Updated | 2026/03/06 23:36 |
| Issue | 8377081 |
Summary
Enhance the security of Java applications by providing an implementation of the Argon2 password hashing algorithm. Argon2 provides additional protection against brute-force password guessing attacks and was the winner of the 2015 Password Hashing Competition.
Goals
- Provide a javax.crypto.KDF implementation of the Argon2id variant of Argon2, as specified in RFC 9106.
Motivation
The Java Platform should offer better support for password hashing algorithms beyond PBKDF2. PBKDF2 is compute-bound and low-memory, which maps well to massively parallel hardware and makes it susceptible to offline cracking with graphics processing units (GPUs) or application-specific integrated circuits (ASICs).
Argon2 is a memory-hard algorithm. Memory-hardness increases the cost of large-scale password guessing by limiting the degree to which attackers can exploit specialized hardware. For example, if each guess requires 64 MiB of memory, then a device with 8 GiB of available memory can execute only about 128 guesses in parallel, rather than thousands or millions.
The Java Platform should provide a standard memory-hard password hashing algorithm. OpenSSL, BouncyCastle and many other toolkits/libraries already support Argon2.
Description
Argon2 defines three variants:
- Argon2d uses data-dependent memory access, it provides better protection against time-memory trade-off (TMTO) attacks.
- Argon2i uses data-independent memory access, it provides better protection against side-channel attacks.
- Argon2id is a hybrid design, it works as Argon2i for the first half of the first pass over the memory and as Argon2d for the rest. Per RFC 9106 "Argon2id MUST be supported by any implementation of this document".
This JEP proposes to implement Argon2id, thus offering a balance between side-channel resistance and TMTO protection. The algorithm will be implemented as a new KDF service of SunJCE provider, adhering to the architecture introduced in JEP 510.
Argon2id is parameterized by memory (m, in KiB), iterations (t) and parallelism (p). These parameters allow applications to tune computational and memory cost according to their deployment requirements.
Integration with the KDF API
-
Argon2id is exposed as a standard KDF algorithm named "ARGON2ID". Applications obtain an instance using:
KDF.getInstance("ARGON2ID"); -
Argon2 inputs are represented by
Argon2ParameterSpecclass:public final class Argon2ParameterSpec implements AlgorithmParameterSpec
Code Example
Argon2ParameterSpec param =
Argon2ParameterSpec.newBuilder()
.parallelism(p).memoryKiB(m).iterations(t)
.secret(secret).ad(associatedData)
.nonce(nonce).tagLen(outputLen).build(password);
KDF k = KDF.getInstance("ARGON2ID");
// Generate password hash as a byte array.
byte[] value = k.deriveData(param);
// Generate output as a SecretKey.
SecretKey key = k.deriveKey("Generic", param);
Security Considerations
- Validate algorithm parameters to ensure they stay within their defined ranges.
Side-Channel Considerations
- Applications verifying passwords should compare derived values in constant time.
Alternatives
- PBKDF2 is a current JDK built-in option. It is tunable via iterations, but remains compute-bound.
- bcrypt is widely deployed but not memory-hard by modern standards.
- scrypt is memory-hard but permits more efficient TMTO attacks than Argon2.
Testing
- Verification against RFC 9106 known-answer test vectors.
- Boundary and exception testing.
- Regression testing within the SunJCE provider.
Risks and Assumptions
- Argon2's memory-hardness relies on the JVM's ability to allocate large blocks of memory.
- Runtime effects (e.g., GC activity) may introduce timing variability; callers should not treat execution time as constant.
- The strength is not fixed. It depends entirely on the algorithm's parameters. If weak parameters are used, Argon2 becomes weak. As the memory (m) decreases, the iterations (t) must increase to maintain security levels.
Appendix
Migration from PBKDF2
PBKDF2 is implemented via javax.crypto.SecretKeyFactory while this JEP proposes to implement Argon2id via javax.crypto.KDF API. Java applications wishing to migrate from PBKDF2 to Argon2id will need to make code modifications to adopt KDF API.
While adopting Argon2id requires code changes, migrating stored credentials requires a data- and rollout-strategy as well, since PBKDF2 and Argon2id outputs are not interchangeable. Recommended strategies include:
- Opportunistic migration during user authentication.
- Rehashing existing PBKDF2 hash values with Argon2id (double hashing).
Recommended Parameter Profiles (Non-Normative Guidance)
RFC 9106 lists 2 uniformly safe options for Argon2id:
- High-security: m=2 GiB, t=1, p=4
- Memory-constrained: m=64 MiB, t=3, p=4