|
@@ -23,6 +23,8 @@ import org.springframework.security.crypto.codec.Utf8;
|
|
|
import org.springframework.security.crypto.keygen.BytesKeyGenerator;
|
|
|
import org.springframework.security.crypto.keygen.KeyGenerators;
|
|
|
|
|
|
+import java.security.MessageDigest;
|
|
|
+
|
|
|
/**
|
|
|
* This {@link PasswordEncoder} is provided for legacy purposes only and is not considered
|
|
|
* secure.
|
|
@@ -79,7 +81,7 @@ public final class StandardPasswordEncoder implements PasswordEncoder {
|
|
|
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
|
|
byte[] digested = decode(encodedPassword);
|
|
|
byte[] salt = subArray(digested, 0, saltGenerator.getKeyLength());
|
|
|
- return matches(digested, digest(rawPassword, salt));
|
|
|
+ return MessageDigest.isEqual(digested, digest(rawPassword, salt));
|
|
|
}
|
|
|
|
|
|
// internal helpers
|
|
@@ -105,21 +107,6 @@ public final class StandardPasswordEncoder implements PasswordEncoder {
|
|
|
return Hex.decode(encodedPassword);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Constant time comparison to prevent against timing attacks.
|
|
|
- */
|
|
|
- private boolean matches(byte[] expected, byte[] actual) {
|
|
|
- if (expected.length != actual.length) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- int result = 0;
|
|
|
- for (int i = 0; i < expected.length; i++) {
|
|
|
- result |= expected[i] ^ actual[i];
|
|
|
- }
|
|
|
- return result == 0;
|
|
|
- }
|
|
|
-
|
|
|
private static final int DEFAULT_ITERATIONS = 1024;
|
|
|
|
|
|
}
|