Skip to content

Commit b2d4c52

Browse files
Add documentation for Password4j-based password encoders for Argon2, BCrypt, Scrypt, PBKDF2, and Balloon hashing
Closes gh-17706 Signed-off-by: M.Bozorgmehr <[email protected]>
1 parent 2d74f9c commit b2d4c52

File tree

2 files changed

+224
-0
lines changed

2 files changed

+224
-0
lines changed

docs/modules/ROOT/pages/features/authentication/password-storage.adoc

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,221 @@ There are a significant number of other `PasswordEncoder` implementations that e
463463
They are all deprecated to indicate that they are no longer considered secure.
464464
However, there are no plans to remove them, since it is difficult to migrate existing legacy systems.
465465

466+
[[authentication-password-storage-password4j]]
467+
== Password4j-based Password Encoders
468+
469+
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.
470+
471+
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.
472+
473+
All Password4j-based encoders are thread-safe and can be shared across multiple threads.
474+
475+
[[authentication-password-storage-password4j-argon2]]
476+
=== Argon2Password4jPasswordEncoder
477+
478+
The `Argon2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Argon2[Argon2] algorithm via the Password4j library to hash passwords.
479+
This provides an alternative to Spring Security's built-in `Argon2PasswordEncoder` with different configuration options and potential performance characteristics.
480+
481+
Argon2 is the winner of the https://en.wikipedia.org/wiki/Password_Hashing_Competition[Password Hashing Competition] and is recommended for new applications.
482+
This implementation leverages Password4j's Argon2 support which properly includes the salt in the output hash.
483+
484+
.Argon2Password4jPasswordEncoder
485+
[tabs]
486+
======
487+
Java::
488+
+
489+
[source,java,role="primary"]
490+
----
491+
// Create an encoder with default settings
492+
Argon2Password4jPasswordEncoder encoder = new Argon2Password4jPasswordEncoder();
493+
String result = encoder.encode("myPassword");
494+
assertTrue(encoder.matches("myPassword", result));
495+
496+
// Create an encoder with custom Argon2 function
497+
Argon2Function customArgon2 = Argon2Function.getInstance(65536, 3, 4, 32, Argon2.ID);
498+
Argon2Password4jPasswordEncoder customEncoder = new Argon2Password4jPasswordEncoder(customArgon2);
499+
----
500+
501+
Kotlin::
502+
+
503+
[source,kotlin,role="secondary"]
504+
----
505+
// Create an encoder with default settings
506+
val encoder = Argon2Password4jPasswordEncoder()
507+
val result: String = encoder.encode("myPassword")
508+
assertTrue(encoder.matches("myPassword", result))
509+
510+
// Create an encoder with custom Argon2 function
511+
val customArgon2 = Argon2Function.getInstance(65536, 3, 4, 32, Argon2.ID)
512+
val customEncoder = Argon2Password4jPasswordEncoder(customArgon2)
513+
----
514+
======
515+
516+
[[authentication-password-storage-password4j-bcrypt]]
517+
=== BcryptPassword4jPasswordEncoder
518+
519+
The `BcryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Bcrypt[BCrypt] algorithm via the Password4j library to hash passwords.
520+
This provides an alternative to Spring Security's built-in `BCryptPasswordEncoder` with Password4j's implementation characteristics.
521+
522+
BCrypt is a well-established password hashing algorithm that includes built-in salt generation and is resistant to rainbow table attacks.
523+
This implementation leverages Password4j's BCrypt support which properly includes the salt in the output hash.
524+
525+
.BcryptPassword4jPasswordEncoder
526+
[tabs]
527+
======
528+
Java::
529+
+
530+
[source,java,role="primary"]
531+
----
532+
// Create an encoder with default settings
533+
BcryptPassword4jPasswordEncoder encoder = new BcryptPassword4jPasswordEncoder();
534+
String result = encoder.encode("myPassword");
535+
assertTrue(encoder.matches("myPassword", result));
536+
537+
// Create an encoder with custom round count
538+
BcryptFunction customBcrypt = BcryptFunction.getInstance(12);
539+
BcryptPassword4jPasswordEncoder customEncoder = new BcryptPassword4jPasswordEncoder(customBcrypt);
540+
----
541+
542+
Kotlin::
543+
+
544+
[source,kotlin,role="secondary"]
545+
----
546+
// Create an encoder with default settings
547+
val encoder = BcryptPassword4jPasswordEncoder()
548+
val result: String = encoder.encode("myPassword")
549+
assertTrue(encoder.matches("myPassword", result))
550+
551+
// Create an encoder with custom round count
552+
val customBcrypt = BcryptFunction.getInstance(12)
553+
val customEncoder = BcryptPassword4jPasswordEncoder(customBcrypt)
554+
----
555+
======
556+
557+
[[authentication-password-storage-password4j-scrypt]]
558+
=== ScryptPassword4jPasswordEncoder
559+
560+
The `ScryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Scrypt[SCrypt] algorithm via the Password4j library to hash passwords.
561+
This provides an alternative to Spring Security's built-in `SCryptPasswordEncoder` with Password4j's implementation characteristics.
562+
563+
SCrypt is a memory-hard password hashing algorithm designed to be resistant to hardware brute-force attacks.
564+
This implementation leverages Password4j's SCrypt support which properly includes the salt in the output hash.
565+
566+
.ScryptPassword4jPasswordEncoder
567+
[tabs]
568+
======
569+
Java::
570+
+
571+
[source,java,role="primary"]
572+
----
573+
// Create an encoder with default settings
574+
ScryptPassword4jPasswordEncoder encoder = new ScryptPassword4jPasswordEncoder();
575+
String result = encoder.encode("myPassword");
576+
assertTrue(encoder.matches("myPassword", result));
577+
578+
// Create an encoder with custom SCrypt parameters
579+
ScryptFunction customScrypt = ScryptFunction.getInstance(32768, 8, 1, 32);
580+
ScryptPassword4jPasswordEncoder customEncoder = new ScryptPassword4jPasswordEncoder(customScrypt);
581+
----
582+
583+
Kotlin::
584+
+
585+
[source,kotlin,role="secondary"]
586+
----
587+
// Create an encoder with default settings
588+
val encoder = ScryptPassword4jPasswordEncoder()
589+
val result: String = encoder.encode("myPassword")
590+
assertTrue(encoder.matches("myPassword", result))
591+
592+
// Create an encoder with custom SCrypt parameters
593+
val customScrypt = ScryptFunction.getInstance(32768, 8, 1, 32)
594+
val customEncoder = ScryptPassword4jPasswordEncoder(customScrypt)
595+
----
596+
======
597+
598+
[[authentication-password-storage-password4j-pbkdf2]]
599+
=== Pbkdf2Password4jPasswordEncoder
600+
601+
The `Pbkdf2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/PBKDF2[PBKDF2] algorithm via the Password4j library to hash passwords.
602+
This provides an alternative to Spring Security's built-in `Pbkdf2PasswordEncoder` with explicit salt management.
603+
604+
PBKDF2 is a key derivation function designed to be computationally expensive to thwart dictionary and brute force attacks.
605+
This implementation handles salt management explicitly since Password4j's PBKDF2 implementation does not include the salt in the output hash.
606+
The encoded password format is: `{salt}:{hash}` where both salt and hash are Base64 encoded.
607+
608+
.Pbkdf2Password4jPasswordEncoder
609+
[tabs]
610+
======
611+
Java::
612+
+
613+
[source,java,role="primary"]
614+
----
615+
// Create an encoder with default settings
616+
Pbkdf2Password4jPasswordEncoder encoder = new Pbkdf2Password4jPasswordEncoder();
617+
String result = encoder.encode("myPassword");
618+
assertTrue(encoder.matches("myPassword", result));
619+
620+
// Create an encoder with custom PBKDF2 function and salt length
621+
PBKDF2Function customPbkdf2 = PBKDF2Function.getInstance(Algorithm.HMAC_SHA256, 100000, 256);
622+
Pbkdf2Password4jPasswordEncoder customEncoder = new Pbkdf2Password4jPasswordEncoder(customPbkdf2, 32);
623+
----
624+
625+
Kotlin::
626+
+
627+
[source,kotlin,role="secondary"]
628+
----
629+
// Create an encoder with default settings
630+
val encoder = Pbkdf2Password4jPasswordEncoder()
631+
val result: String = encoder.encode("myPassword")
632+
assertTrue(encoder.matches("myPassword", result))
633+
634+
// Create an encoder with custom PBKDF2 function and salt length
635+
val customPbkdf2 = PBKDF2Function.getInstance(Algorithm.HMAC_SHA256, 100000, 256)
636+
val customEncoder = Pbkdf2Password4jPasswordEncoder(customPbkdf2, 32)
637+
----
638+
======
639+
640+
[[authentication-password-storage-password4j-balloon]]
641+
=== BalloonHashingPassword4jPasswordEncoder
642+
643+
The `BalloonHashingPassword4jPasswordEncoder` implementation uses the Balloon hashing algorithm via the Password4j library to hash passwords.
644+
Balloon hashing is a memory-hard password hashing algorithm designed to be resistant to both time-memory trade-off attacks and side-channel attacks.
645+
646+
This implementation handles salt management explicitly since Password4j's Balloon hashing implementation does not include the salt in the output hash.
647+
The encoded password format is: `{salt}:{hash}` where both salt and hash are Base64 encoded.
648+
649+
.BalloonHashingPassword4jPasswordEncoder
650+
[tabs]
651+
======
652+
Java::
653+
+
654+
[source,java,role="primary"]
655+
----
656+
// Create an encoder with default settings
657+
BalloonHashingPassword4jPasswordEncoder encoder = new BalloonHashingPassword4jPasswordEncoder();
658+
String result = encoder.encode("myPassword");
659+
assertTrue(encoder.matches("myPassword", result));
660+
661+
// Create an encoder with custom Balloon hashing function and salt length
662+
BalloonHashingFunction customBalloon = BalloonHashingFunction.getInstance(1024, 3, 4, "SHA-256");
663+
BalloonHashingPassword4jPasswordEncoder customEncoder = new BalloonHashingPassword4jPasswordEncoder(customBalloon, 32);
664+
----
665+
666+
Kotlin::
667+
+
668+
[source,kotlin,role="secondary"]
669+
----
670+
// Create an encoder with default settings
671+
val encoder = BalloonHashingPassword4jPasswordEncoder()
672+
val result: String = encoder.encode("myPassword")
673+
assertTrue(encoder.matches("myPassword", result))
674+
675+
// Create an encoder with custom Balloon hashing function and salt length
676+
val customBalloon = BalloonHashingFunction.getInstance(1024, 3, 4, "SHA-256")
677+
val customEncoder = BalloonHashingPassword4jPasswordEncoder(customBalloon, 32)
678+
----
679+
======
680+
466681
[[authentication-password-storage-configuration]]
467682
== Password Storage Configuration
468683

docs/modules/ROOT/pages/whats-new.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ Java::
3535
http.csrf((csrf) -> csrf.spa());
3636
----
3737

38+
== Crypto
39+
40+
* Added Password4j-based password encoders providing alternative implementations for popular hashing algorithms:
41+
** `Argon2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-argon2[Argon2 implementation using Password4j]
42+
** `BcryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-bcrypt[BCrypt implementation using Password4j]
43+
** `ScryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-scrypt[SCrypt implementation using Password4j]
44+
** `Pbkdf2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-pbkdf2[PBKDF2 implementation using Password4j]
45+
** `BalloonHashingPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#authentication-password-storage-password4j-balloon[Balloon Hashing implementation using Password4j]
46+
3847
== Data
3948

4049
* Added support to Authorized objects for Spring Data types

0 commit comments

Comments
 (0)