|
|
@@ -463,6 +463,221 @@ There are a significant number of other `PasswordEncoder` implementations that e
|
|
|
They are all deprecated to indicate that they are no longer considered secure.
|
|
|
However, there are no plans to remove them, since it is difficult to migrate existing legacy systems.
|
|
|
|
|
|
+[[authentication-password-storage-password4j]]
|
|
|
+== Password4j-based Password Encoders
|
|
|
+
|
|
|
+Spring Security 7.0 introduces alternative password encoder implementations based on the https://github.com/Password4j/password4j[Password4j] library. These encoders provide additional options for popular hashing algorithms and can be used as alternatives to the existing Spring Security implementations.
|
|
|
+
|
|
|
+The Password4j library is a Java cryptographic library that focuses on password hashing with support for multiple algorithms. These encoders are particularly useful when you need specific algorithm configurations or want to leverage Password4j's optimizations.
|
|
|
+
|
|
|
+All Password4j-based encoders are thread-safe and can be shared across multiple threads.
|
|
|
+
|
|
|
+[[authentication-password-storage-password4j-argon2]]
|
|
|
+=== Argon2Password4jPasswordEncoder
|
|
|
+
|
|
|
+The `Argon2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Argon2[Argon2] algorithm via the Password4j library to hash passwords.
|
|
|
+This provides an alternative to Spring Security's built-in `Argon2PasswordEncoder` with different configuration options and potential performance characteristics.
|
|
|
+
|
|
|
+Argon2 is the winner of the https://en.wikipedia.org/wiki/Password_Hashing_Competition[Password Hashing Competition] and is recommended for new applications.
|
|
|
+This implementation leverages Password4j's Argon2 support which properly includes the salt in the output hash.
|
|
|
+
|
|
|
+.Argon2Password4jPasswordEncoder
|
|
|
+[tabs]
|
|
|
+======
|
|
|
+Java::
|
|
|
++
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+Argon2Password4jPasswordEncoder encoder = new Argon2Password4jPasswordEncoder();
|
|
|
+String result = encoder.encode("myPassword");
|
|
|
+assertTrue(encoder.matches("myPassword", result));
|
|
|
+
|
|
|
+// Create an encoder with custom Argon2 function
|
|
|
+Argon2Function customArgon2 = Argon2Function.getInstance(65536, 3, 4, 32, Argon2.ID);
|
|
|
+Argon2Password4jPasswordEncoder customEncoder = new Argon2Password4jPasswordEncoder(customArgon2);
|
|
|
+----
|
|
|
+
|
|
|
+Kotlin::
|
|
|
++
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+val encoder = Argon2Password4jPasswordEncoder()
|
|
|
+val result: String = encoder.encode("myPassword")
|
|
|
+assertTrue(encoder.matches("myPassword", result))
|
|
|
+
|
|
|
+// Create an encoder with custom Argon2 function
|
|
|
+val customArgon2 = Argon2Function.getInstance(65536, 3, 4, 32, Argon2.ID)
|
|
|
+val customEncoder = Argon2Password4jPasswordEncoder(customArgon2)
|
|
|
+----
|
|
|
+======
|
|
|
+
|
|
|
+[[authentication-password-storage-password4j-bcrypt]]
|
|
|
+=== BcryptPassword4jPasswordEncoder
|
|
|
+
|
|
|
+The `BcryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Bcrypt[BCrypt] algorithm via the Password4j library to hash passwords.
|
|
|
+This provides an alternative to Spring Security's built-in `BCryptPasswordEncoder` with Password4j's implementation characteristics.
|
|
|
+
|
|
|
+BCrypt is a well-established password hashing algorithm that includes built-in salt generation and is resistant to rainbow table attacks.
|
|
|
+This implementation leverages Password4j's BCrypt support which properly includes the salt in the output hash.
|
|
|
+
|
|
|
+.BcryptPassword4jPasswordEncoder
|
|
|
+[tabs]
|
|
|
+======
|
|
|
+Java::
|
|
|
++
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+BcryptPassword4jPasswordEncoder encoder = new BcryptPassword4jPasswordEncoder();
|
|
|
+String result = encoder.encode("myPassword");
|
|
|
+assertTrue(encoder.matches("myPassword", result));
|
|
|
+
|
|
|
+// Create an encoder with custom round count
|
|
|
+BcryptFunction customBcrypt = BcryptFunction.getInstance(12);
|
|
|
+BcryptPassword4jPasswordEncoder customEncoder = new BcryptPassword4jPasswordEncoder(customBcrypt);
|
|
|
+----
|
|
|
+
|
|
|
+Kotlin::
|
|
|
++
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+val encoder = BcryptPassword4jPasswordEncoder()
|
|
|
+val result: String = encoder.encode("myPassword")
|
|
|
+assertTrue(encoder.matches("myPassword", result))
|
|
|
+
|
|
|
+// Create an encoder with custom round count
|
|
|
+val customBcrypt = BcryptFunction.getInstance(12)
|
|
|
+val customEncoder = BcryptPassword4jPasswordEncoder(customBcrypt)
|
|
|
+----
|
|
|
+======
|
|
|
+
|
|
|
+[[authentication-password-storage-password4j-scrypt]]
|
|
|
+=== ScryptPassword4jPasswordEncoder
|
|
|
+
|
|
|
+The `ScryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Scrypt[SCrypt] algorithm via the Password4j library to hash passwords.
|
|
|
+This provides an alternative to Spring Security's built-in `SCryptPasswordEncoder` with Password4j's implementation characteristics.
|
|
|
+
|
|
|
+SCrypt is a memory-hard password hashing algorithm designed to be resistant to hardware brute-force attacks.
|
|
|
+This implementation leverages Password4j's SCrypt support which properly includes the salt in the output hash.
|
|
|
+
|
|
|
+.ScryptPassword4jPasswordEncoder
|
|
|
+[tabs]
|
|
|
+======
|
|
|
+Java::
|
|
|
++
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+ScryptPassword4jPasswordEncoder encoder = new ScryptPassword4jPasswordEncoder();
|
|
|
+String result = encoder.encode("myPassword");
|
|
|
+assertTrue(encoder.matches("myPassword", result));
|
|
|
+
|
|
|
+// Create an encoder with custom SCrypt parameters
|
|
|
+ScryptFunction customScrypt = ScryptFunction.getInstance(32768, 8, 1, 32);
|
|
|
+ScryptPassword4jPasswordEncoder customEncoder = new ScryptPassword4jPasswordEncoder(customScrypt);
|
|
|
+----
|
|
|
+
|
|
|
+Kotlin::
|
|
|
++
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+val encoder = ScryptPassword4jPasswordEncoder()
|
|
|
+val result: String = encoder.encode("myPassword")
|
|
|
+assertTrue(encoder.matches("myPassword", result))
|
|
|
+
|
|
|
+// Create an encoder with custom SCrypt parameters
|
|
|
+val customScrypt = ScryptFunction.getInstance(32768, 8, 1, 32)
|
|
|
+val customEncoder = ScryptPassword4jPasswordEncoder(customScrypt)
|
|
|
+----
|
|
|
+======
|
|
|
+
|
|
|
+[[authentication-password-storage-password4j-pbkdf2]]
|
|
|
+=== Pbkdf2Password4jPasswordEncoder
|
|
|
+
|
|
|
+The `Pbkdf2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/PBKDF2[PBKDF2] algorithm via the Password4j library to hash passwords.
|
|
|
+This provides an alternative to Spring Security's built-in `Pbkdf2PasswordEncoder` with explicit salt management.
|
|
|
+
|
|
|
+PBKDF2 is a key derivation function designed to be computationally expensive to thwart dictionary and brute force attacks.
|
|
|
+This implementation handles salt management explicitly since Password4j's PBKDF2 implementation does not include the salt in the output hash.
|
|
|
+The encoded password format is: `{salt}:{hash}` where both salt and hash are Base64 encoded.
|
|
|
+
|
|
|
+.Pbkdf2Password4jPasswordEncoder
|
|
|
+[tabs]
|
|
|
+======
|
|
|
+Java::
|
|
|
++
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+Pbkdf2Password4jPasswordEncoder encoder = new Pbkdf2Password4jPasswordEncoder();
|
|
|
+String result = encoder.encode("myPassword");
|
|
|
+assertTrue(encoder.matches("myPassword", result));
|
|
|
+
|
|
|
+// Create an encoder with custom PBKDF2 function and salt length
|
|
|
+PBKDF2Function customPbkdf2 = PBKDF2Function.getInstance(Algorithm.HMAC_SHA256, 100000, 256);
|
|
|
+Pbkdf2Password4jPasswordEncoder customEncoder = new Pbkdf2Password4jPasswordEncoder(customPbkdf2, 32);
|
|
|
+----
|
|
|
+
|
|
|
+Kotlin::
|
|
|
++
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+val encoder = Pbkdf2Password4jPasswordEncoder()
|
|
|
+val result: String = encoder.encode("myPassword")
|
|
|
+assertTrue(encoder.matches("myPassword", result))
|
|
|
+
|
|
|
+// Create an encoder with custom PBKDF2 function and salt length
|
|
|
+val customPbkdf2 = PBKDF2Function.getInstance(Algorithm.HMAC_SHA256, 100000, 256)
|
|
|
+val customEncoder = Pbkdf2Password4jPasswordEncoder(customPbkdf2, 32)
|
|
|
+----
|
|
|
+======
|
|
|
+
|
|
|
+[[authentication-password-storage-password4j-balloon]]
|
|
|
+=== BalloonHashingPassword4jPasswordEncoder
|
|
|
+
|
|
|
+The `BalloonHashingPassword4jPasswordEncoder` implementation uses the Balloon hashing algorithm via the Password4j library to hash passwords.
|
|
|
+Balloon hashing is a memory-hard password hashing algorithm designed to be resistant to both time-memory trade-off attacks and side-channel attacks.
|
|
|
+
|
|
|
+This implementation handles salt management explicitly since Password4j's Balloon hashing implementation does not include the salt in the output hash.
|
|
|
+The encoded password format is: `{salt}:{hash}` where both salt and hash are Base64 encoded.
|
|
|
+
|
|
|
+.BalloonHashingPassword4jPasswordEncoder
|
|
|
+[tabs]
|
|
|
+======
|
|
|
+Java::
|
|
|
++
|
|
|
+[source,java,role="primary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+BalloonHashingPassword4jPasswordEncoder encoder = new BalloonHashingPassword4jPasswordEncoder();
|
|
|
+String result = encoder.encode("myPassword");
|
|
|
+assertTrue(encoder.matches("myPassword", result));
|
|
|
+
|
|
|
+// Create an encoder with custom Balloon hashing function and salt length
|
|
|
+BalloonHashingFunction customBalloon = BalloonHashingFunction.getInstance(1024, 3, 4, "SHA-256");
|
|
|
+BalloonHashingPassword4jPasswordEncoder customEncoder = new BalloonHashingPassword4jPasswordEncoder(customBalloon, 32);
|
|
|
+----
|
|
|
+
|
|
|
+Kotlin::
|
|
|
++
|
|
|
+[source,kotlin,role="secondary"]
|
|
|
+----
|
|
|
+// Create an encoder with default settings
|
|
|
+val encoder = BalloonHashingPassword4jPasswordEncoder()
|
|
|
+val result: String = encoder.encode("myPassword")
|
|
|
+assertTrue(encoder.matches("myPassword", result))
|
|
|
+
|
|
|
+// Create an encoder with custom Balloon hashing function and salt length
|
|
|
+val customBalloon = BalloonHashingFunction.getInstance(1024, 3, 4, "SHA-256")
|
|
|
+val customEncoder = BalloonHashingPassword4jPasswordEncoder(customBalloon, 32)
|
|
|
+----
|
|
|
+======
|
|
|
+
|
|
|
[[authentication-password-storage-configuration]]
|
|
|
== Password Storage Configuration
|
|
|
|