PasswordEncoder derives a stored password representation and verifies a candidate against it without recovering the original password.
Spring PasswordEncoder: salted verification rather than reversible storage
This lesson uses the downloadable source kit: Java 21, Spring Boot 4.0.8 and its managed Spring Framework 7 dependencies. The version is pinned for repeatable builds.
Compare through the encoder
The fixture’s delegating encoder produces different salted encodings for the same password. The test verifies both against the original and rejects an incorrect candidate. Comparing a new encoding string to the stored string would fail because the salt changes the result.
The stored encoding includes the algorithm identifier used by the delegating encoder. Keep it when persisting the value so verification can select the intended algorithm. Truncating a database column can corrupt that representation.
Hashing is only one part of account security
Password hashing does not establish session expiry, login throttling, recovery ownership or protection from credential stuffing. Do not present the small source-kit user store as a complete identity service.
Opaque token generation is a different operation. Passwords are low-entropy user input that need slow verification; random bearer credentials have a different lookup and storage design. Reusing one representation everywhere hides that difference.
Checked source
var encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
String first = encoder.encode("fixture-password");
String second = encoder.encode("fixture-password");
boolean verified = encoder.matches("fixture-password", first);
boolean rejected = !encoder.matches("incorrect", first);Test the boundary
Run mvn test in the source-kit directory. HttpSecurityBoundaryTest.passwordHashesUseSaltAndMatchOriginal checks the behavior described here. Java excerpts belong to the named source-kit classes; they are not independent source files unless the complete class is shown.
Costs and boundaries
Adaptive hashing intentionally costs CPU. Choose and measure the work factor on the actual service hardware, then bound authentication admission. Faster verification is not automatically a security improvement.
Common Mistakes
- Use matches rather than comparing newly encoded strings.
- Preserve the encoding identifier and full stored value.
- Do not log passwords or complete bearer credentials.
Read next
Spring Security filter chain: authentication, CSRF and request order, Java SecureRandom: token entropy, encoding and comparison boundaries, Java byte streams: partial reads and bounded copying.
