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);
|
||||
}
|
||||
|
||||
@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) {
|
||||
String[] parts = encodedPassword.split("\\$");
|
||||
|
||||
|
|
|
@ -116,5 +116,35 @@ public class SCryptPasswordEncoderTests {
|
|||
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…
Reference in New Issue