Class ModularPbkdf2PasswordEncoder
- All Implemented Interfaces:
PasswordEncoder
PBKDF2 password hashes in the self-describing formats other frameworks store, read as they write them: the digest and the round count come from the stored value, so every row verifies whatever its era's settings were.
| format | stored value |
|---|---|
ModularPbkdf2PasswordEncoder.Format.DJANGO |
pbkdf2_sha256$<rounds>$<salt>$<base64 hash> (also pbkdf2_sha1) |
ModularPbkdf2PasswordEncoder.Format.PASSLIB |
$pbkdf2-sha256$<rounds>$<ab64 salt>$<ab64 hash> (also $pbkdf2$, $pbkdf2-sha512$) |
ModularPbkdf2PasswordEncoder.Format.WERKZEUG |
pbkdf2:sha256:<rounds>$<salt>$<hex hash> (also sha1, sha512) |
Register it under an id of its own and give the imported hashes that prefix:
Map<String, PasswordEncoder> encoders = new LinkedHashMap<>();
encoders.put("pbkdf2-sha256", new Pbkdf2Sha256PasswordEncoder());
encoders.put("django", new ModularPbkdf2PasswordEncoder(ModularPbkdf2PasswordEncoder.Format.DJANGO));
PasswordEncoder passwords = new DelegatingPasswordEncoder("pbkdf2-sha256", encoders);
// a row imported as "{django}pbkdf2_sha256$600000$..." verifies, and is
// re-hashed with the default when its owner signs in
upgradeEncoding(String) is true for every value: these are formats to
migrate away from, not to keep writing.
A stored value names its own work factor, so it is bounded. One above
maxRounds (5,000,000 by default) does not verify -- a hash that asked for
a billion rounds would hold the host thread it runs on for minutes. Werkzeug
values without a round count are refused too: the count they used was the
default of whichever Werkzeug release wrote them, and guessing it would
either fail every such login or need one PBKDF2 run per guess.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumThe stored layouts read. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionencode(CharSequence rawPassword) A new SHA-256 hash in this format.booleanisReadable(String encodedPassword) WhetherencodedPasswordis a value of this format this encoder would try to verify: the layout, a known digest and a round count withinmaxRounds.booleanmatches(CharSequence rawPassword, String encodedPassword) WhetherrawPasswordis the passwordencodedPasswordwas made from.voidsetEncodeRounds(int rounds) Roundsencode(CharSequence)writes.voidsetMaxRounds(int maxRounds) The most rounds a stored value may ask for.booleanupgradeEncoding(String encodedPassword) WhetherencodedPasswordshould be encoded again for better protection: it was made by an older scheme, or with fewer rounds than this encoder uses now.
-
Constructor Details
-
ModularPbkdf2PasswordEncoder
-
-
Method Details
-
setMaxRounds
public void setMaxRounds(int maxRounds) The most rounds a stored value may ask for. Default 5,000,000. -
setEncodeRounds
public void setEncodeRounds(int rounds) Roundsencode(CharSequence)writes. Default 600,000 with SHA-256. -
encode
A new SHA-256 hash in this format. Meant for fixtures and for tests of a migration; a running server writes its default encoder's format.- Specified by:
encodein interfacePasswordEncoder
-
matches
Description copied from interface:PasswordEncoderWhetherrawPasswordis the passwordencodedPasswordwas made from.- Specified by:
matchesin interfacePasswordEncoder
-
upgradeEncoding
Description copied from interface:PasswordEncoderWhetherencodedPasswordshould be encoded again for better protection: it was made by an older scheme, or with fewer rounds than this encoder uses now.- Specified by:
upgradeEncodingin interfacePasswordEncoder
-
isReadable
WhetherencodedPasswordis a value of this format this encoder would try to verify: the layout, a known digest and a round count withinmaxRounds. What a migration asks before importing a row.
-