-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Update default configuration for PasswordEncoders #11904
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update default configuration for PasswordEncoders #11904
Conversation
@Sc00bz @larsgrefer Thank you for all your valuable feedback so far. When you have a moment, I would appreciate it if you can take a look at the updates in this PR and provide any feedback. Thank you. |
Your names are incorrect "cpuCost" is "N" (number of blocks) and "memoryCost" is "r" or "rate" (block size). Note N*r is memory cost and you can think of parallelism as a time cost. Pbkdf2PasswordEncoder.java, line 53:
You might get complaints with 64 bits being low (128 to 256 bits is normal). Note 64 bits is fine because 99.99%+ of salts will be globally unique. SCryptPasswordEncoder.java, line 69:
512 bits for a salt is overkill. |
Yeah, I realize the member names might be misleading but if you look at the javadoc: /**
* Creates a new instance
*
* @param cpuCost cpu cost of the algorithm (as defined in scrypt this is N). must be
* power of 2 greater than 1. Default is currently 16,384 or 2^14)
* @param memoryCost memory cost of the algorithm (as defined in scrypt this is r)
* Default is currently 8.
* ...
*/
public SCryptPasswordEncoder(int cpuCost, int memoryCost, int parallelization, int keyLength, int saltLength) {
I'll update the Thanks for the feedback. |
19f07a1
to
ff0db78
Compare
ff0db78
to
a173a71
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your idea around the minimums based upon the Spring Security version. I'd like to propose we take it a little further to provide an easier migration path for our users by allowing users to easily opt into changes in 5.8. Rather than changing the default constructor, I'd like to propose we do a few things:
Starting in 5.8
- Introduce a static factory method that is named with the major and minor version of Spring Security that introduced the defaults for each encoder. For example defaultsForSecurity5_0()
- Deprecate default constructors
- Introduce a static factory method that is named with 6.0 version of Spring Security that introduces the defaults provided here.
In 6.0 remove the default constructor, but preserve the static factory methods as deprecated methods so that applications can continue to work.
Please also ensure there is a test for each instance of the new password encoder validating a password that was encoded from the older settings. Please hard code the encoded password.
// See gh-10506 Update PasswordEncoder Minimums | ||
Pbkdf2PasswordEncoder pbkdf2PasswordEncoder = new Pbkdf2PasswordEncoder("", 8, 185000, 256); | ||
pbkdf2PasswordEncoder.setAlgorithm(Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA1); | ||
encoders.put("pbkdf2", pbkdf2PasswordEncoder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have an instance of Pbkdf2 added that uses the new defaults added because without it there is no way to encode passwords with pbkdf2 new defaults.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added new encodingId
pbkdf2-sha256
that is configured with the new defaults.
a173a71
to
cddd3ef
Compare
cddd3ef
to
665030a
Compare
@rwinch I applied the static factory methods to However, I did not apply the static factory methods to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left feedback inline. In addition, please update the other encoders to have static factory methods as we discussed offline.
@@ -71,7 +73,8 @@ public static PasswordEncoder createDelegatingPasswordEncoder() { | |||
encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder()); | |||
encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5")); | |||
encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance()); | |||
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder()); | |||
encoders.put("pbkdf2", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_5()); | |||
encoders.put("pbkdf2-sha256", Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the -sha256 should be also related to v5_8 or all alg parameters since there are other parameters that could change. I realize that the recommendations are based on the algorithm, but these recommendations are for now and may change. That would make it difficult for us to provide additional settings later.
My quick thought is that I'd prefer the id to contain all parameters even if it is verbose as this is easier for users to understand and will be similar to other encodings work (I.e. phc, bcrypt, etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My quick thought is that I'd prefer the id to contain all parameters even if it is verbose
I still think it would be too verbose, for example, the encodingId
for pbkdf2
would be something like pbkdf2[salt=16;iterations=310000;algorithm=sha256;hashWidth=256]
.
Instead, I decided to align the encodingId
to the static factory method name, for example:
argon2@SpringSecurity_v5_8
->Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8()
scrypt@SpringSecurity_v5_8
->SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8()
pbkdf2@SpringSecurity_v5_8
->Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
The recommended minimums for Argon2, as per OWASP Cheat Sheet Series (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html), are: Use Argon2id with a minimum configuration of 15 MiB of memory, an iteration count of 2, and 1 degree of parallelism. Previous default configuration: memory=4, iterations=3, parallelism=1 New default configuration: memory=16, iterations=2, parallelism=1 Issue spring-projectsgh-10506
The recommended minimums for scrypt, as per OWASP Cheat Sheet Series (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html), are: Use scrypt with a minimum CPU/memory cost parameter of (2^16), a minimum block size of 8 (1024 bytes), and a parallelization parameter of 1. Previous default configuration: cpuCost=16384, memoryCost=8, parallelism=1 New default configuration: cpuCost=65536, memoryCost=8, parallelism=1 The default salt length was also updated from 64 to 16. Issue spring-projectsgh-10506
The recommended minimums for PBKDF2, as per OWASP Cheat Sheet Series (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html), are: If FIPS-140 compliance is required, use PBKDF2 with a work factor of 310,000 or more and set with an internal hash function of HMAC-SHA-256. Previous default configuration: algorithm=SHA1, iterations=185000, hashLength=256 New default configuration: algorithm=SHA256, iterations=310000, hashLength=256 The default salt length was also updated from 8 to 16. Closes spring-projectsgh-10506, Closes spring-projectsgh-10489
665030a
to
c50441b
Compare
Update default configuration for
Argon2PasswordEncoder
,SCryptPasswordEncoder
andPbkdf2PasswordEncoder
, as per recommended minimums outlined in OWASP Cheat Sheet Series .Argon2PasswordEncoder
Recommendation:
Use Argon2id with a minimum configuration of 15 MiB of memory, an iteration count of 2, and 1 degree of parallelism.
Previous default configuration:
memory=4, iterations=3, parallelism=1
New default configuration:
memory=16, iterations=2, parallelism=1
SCryptPasswordEncoder
Recommendation:
Use scrypt with a minimum CPU/memory cost parameter of (2^16), a minimum block size of 8 (1024 bytes), and a parallelization parameter of 1.
Previous default configuration:
cpuCost=16384, memoryCost=8, parallelism=1
New default configuration:
cpuCost=65536, memoryCost=8, parallelism=1
The default salt length was also updated from 64 to 16.
Pbkdf2PasswordEncoder
Recommendation:
If FIPS-140 compliance is required, use PBKDF2 with a work factor of 310,000 or more and set with an internal hash function of HMAC-SHA-256.
Previous default configuration:
algorithm=SHA1, iterations=185000, hashLength=256
New default configuration:
algorithm=SHA256, iterations=310000, hashLength=256
The default salt length was also updated from 8 to 16.
Closes gh-10506, Closes gh-10489