Pbkdf2PasswordEncoder supports Base64 encoding
Fixes gh-4683
This commit is contained in:
parent
fe8f3afbaf
commit
870b8bf9b2
|
@ -17,6 +17,7 @@ package org.springframework.security.crypto.password;
|
|||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
|
@ -52,6 +53,7 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
|||
private final int hashWidth;
|
||||
private final int iterations;
|
||||
private String algorithm = SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA1.name();
|
||||
private boolean encodeHashAsBase64;
|
||||
|
||||
/**
|
||||
* Constructs a PBKDF2 password encoder with no additional secret value. There will be
|
||||
|
@ -110,16 +112,33 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
|||
this.algorithm = algorithmName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the resulting hash should be encoded as Base64. The default is false which
|
||||
* means it will be encoded in Hex.
|
||||
* @param encodeHashAsBase64 true if encode as Base64, false if should use Hex
|
||||
* (default)
|
||||
*/
|
||||
public void setEncodeHashAsBase64(boolean encodeHashAsBase64) {
|
||||
this.encodeHashAsBase64 = encodeHashAsBase64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
byte[] salt = this.saltGenerator.generateKey();
|
||||
byte[] encoded = encode(rawPassword, salt);
|
||||
return String.valueOf(Hex.encode(encoded));
|
||||
return encode(encoded);
|
||||
}
|
||||
|
||||
private String encode(byte[] bytes) {
|
||||
if(this.encodeHashAsBase64) {
|
||||
return Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
return String.valueOf(Hex.encode(bytes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||
byte[] digested = Hex.decode(encodedPassword);
|
||||
byte[] digested = decode(encodedPassword);
|
||||
byte[] salt = subArray(digested, 0, this.saltGenerator.getKeyLength());
|
||||
return matches(digested, encode(rawPassword, salt));
|
||||
}
|
||||
|
@ -139,6 +158,13 @@ public class Pbkdf2PasswordEncoder implements PasswordEncoder {
|
|||
return result == 0;
|
||||
}
|
||||
|
||||
private byte[] decode(String encodedBytes) {
|
||||
if(this.encodeHashAsBase64) {
|
||||
return Base64.getDecoder().decode(encodedBytes);
|
||||
}
|
||||
return Hex.decode(encodedBytes);
|
||||
}
|
||||
|
||||
private byte[] encode(CharSequence rawPassword, byte[] salt) {
|
||||
try {
|
||||
PBEKeySpec spec = new PBEKeySpec(rawPassword.toString().toCharArray(),
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Arrays;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.security.crypto.codec.Base64;
|
||||
import org.springframework.security.crypto.codec.Hex;
|
||||
import org.springframework.security.crypto.keygen.KeyGenerators;
|
||||
|
||||
|
@ -75,6 +76,25 @@ public class Pbkdf2PasswordEncoderTests {
|
|||
assertThat(fixedHex).isEqualTo(encodedPassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeAndMatchWhenBase64ThenSuccess() {
|
||||
this.encoder.setEncodeHashAsBase64(true);
|
||||
|
||||
String rawPassword = "password";
|
||||
String encodedPassword = this.encoder.encode(rawPassword);
|
||||
assertThat(this.encoder.matches(rawPassword, encodedPassword)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchWhenBase64ThenSuccess() {
|
||||
this.encoder.setEncodeHashAsBase64(true);
|
||||
String rawPassword = "password";
|
||||
String encodedPassword = "3FOwOMcDgxP+z1x/sv184LFY2WVD+ZGMgYP3LPOSmCcDmk1XPYvcCQ==";
|
||||
|
||||
assertThat(this.encoder.matches(rawPassword, encodedPassword)).isTrue();
|
||||
java.util.Base64.getDecoder().decode(encodedPassword); // validate can decode as Base64
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeAndMatchWhenSha256ThenSuccess() {
|
||||
this.encoder.setAlgorithm(Pbkdf2PasswordEncoder.SecretKeyFactoryAlgorithm.PBKDF2WithHmacSHA256);
|
||||
|
|
Loading…
Reference in New Issue