diff --git a/docs/modules/ROOT/pages/features/authentication/password-storage.adoc b/docs/modules/ROOT/pages/features/authentication/password-storage.adoc index 2ea6d68bab..7f0d570601 100644 --- a/docs/modules/ROOT/pages/features/authentication/password-storage.adoc +++ b/docs/modules/ROOT/pages/features/authentication/password-storage.adoc @@ -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 diff --git a/docs/modules/ROOT/pages/whats-new.adoc b/docs/modules/ROOT/pages/whats-new.adoc index 2955ebb821..a5ab6c66e5 100644 --- a/docs/modules/ROOT/pages/whats-new.adoc +++ b/docs/modules/ROOT/pages/whats-new.adoc @@ -35,6 +35,15 @@ Java:: http.csrf((csrf) -> csrf.spa()); ---- +== Crypto + +* Added Password4j-based password encoders providing alternative implementations for popular hashing algorithms: +** `Argon2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-argon2[Argon2 implementation using Password4j] +** `BcryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-bcrypt[BCrypt implementation using Password4j] +** `ScryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-scrypt[SCrypt implementation using Password4j] +** `Pbkdf2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-pbkdf2[PBKDF2 implementation using Password4j] +** `BalloonHashingPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-balloon[Balloon Hashing implementation using Password4j] + == Data * Added support to Authorized objects for Spring Data types