mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-27 14:22:47 +00:00
Allow upgrading between different SCrypt encodings
Fixes gh-7057
This commit is contained in:
parent
742df2cd1d
commit
e95effc839
@ -135,6 +135,30 @@ public class SCryptPasswordEncoder implements PasswordEncoder {
|
|||||||
return decodeAndCheckMatches(rawPassword, encodedPassword);
|
return decodeAndCheckMatches(rawPassword, encodedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean upgradeEncoding(String encodedPassword) {
|
||||||
|
if (encodedPassword == null || encodedPassword.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = encodedPassword.split("\\$");
|
||||||
|
|
||||||
|
if (parts.length != 4) {
|
||||||
|
throw new IllegalArgumentException("Encoded password does not look like SCrypt: " + encodedPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
long params = Long.parseLong(parts[1], 16);
|
||||||
|
|
||||||
|
int cpuCost = (int) Math.pow(2, params >> 16 & 0xffff);
|
||||||
|
int memoryCost = (int) params >> 8 & 0xff;
|
||||||
|
int parallelization = (int) params & 0xff;
|
||||||
|
|
||||||
|
return cpuCost < this.cpuCost
|
||||||
|
|| memoryCost < this.memoryCost
|
||||||
|
|| parallelization < this.parallelization;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private boolean decodeAndCheckMatches(CharSequence rawPassword, String encodedPassword) {
|
private boolean decodeAndCheckMatches(CharSequence rawPassword, String encodedPassword) {
|
||||||
String[] parts = encodedPassword.split("\\$");
|
String[] parts = encodedPassword.split("\\$");
|
||||||
|
|
||||||
|
@ -116,5 +116,35 @@ public class SCryptPasswordEncoderTests {
|
|||||||
new SCryptPasswordEncoder(2, 8, 1, -1, 16);
|
new SCryptPasswordEncoder(2, 8, 1, -1, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upgradeEncoding_nullOrEmptyInput() {
|
||||||
|
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
|
||||||
|
assertThat(encoder.upgradeEncoding(null)).isFalse();
|
||||||
|
assertThat(encoder.upgradeEncoding("")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upgradeEncoding_sameEncoder() {
|
||||||
|
SCryptPasswordEncoder encoder = new SCryptPasswordEncoder();
|
||||||
|
String encoded = encoder.encode("password");
|
||||||
|
assertThat(encoder.upgradeEncoding(encoded)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upgradeEncoding_weakerToStronger() {
|
||||||
|
SCryptPasswordEncoder weakEncoder = new SCryptPasswordEncoder((int) Math.pow(2, 10), 4, 1, 32, 64);
|
||||||
|
SCryptPasswordEncoder strongEncoder = new SCryptPasswordEncoder((int) Math.pow(2, 16), 8, 1, 32, 64);
|
||||||
|
|
||||||
|
String weakPassword = weakEncoder.encode("password");
|
||||||
|
String strongPassword = strongEncoder.encode("password");
|
||||||
|
|
||||||
|
assertThat(strongEncoder.upgradeEncoding(weakPassword)).isTrue();
|
||||||
|
assertThat(weakEncoder.upgradeEncoding(strongPassword)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void upgradeEncoding_invalidInput() {
|
||||||
|
new SCryptPasswordEncoder().upgradeEncoding("not-a-scrypt-password");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user