Refactoring to use Utf8 encoder instead of String.getBytes("UTF-8").
This commit is contained in:
parent
361b77685d
commit
571bfc4869
|
@ -80,11 +80,9 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sha = MessageDigest.getInstance("SHA");
|
sha = MessageDigest.getInstance("SHA");
|
||||||
sha.update(rawPass.getBytes("UTF-8"));
|
sha.update(Utf8.encode(rawPass));
|
||||||
} catch (java.security.NoSuchAlgorithmException e) {
|
} catch (java.security.NoSuchAlgorithmException e) {
|
||||||
throw new IllegalStateException("No SHA implementation available!");
|
throw new IllegalStateException("No SHA implementation available!");
|
||||||
} catch (UnsupportedEncodingException ue) {
|
|
||||||
throw new IllegalStateException("UTF-8 not supported!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (salt != null) {
|
if (salt != null) {
|
||||||
|
|
|
@ -47,13 +47,7 @@ public class Md4PasswordEncoder extends BaseDigestPasswordEncoder {
|
||||||
public String encodePassword(String rawPass, Object salt) {
|
public String encodePassword(String rawPass, Object salt) {
|
||||||
String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
|
String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
|
||||||
|
|
||||||
byte[] passBytes;
|
byte[] passBytes = Utf8.encode(saltedPass);
|
||||||
|
|
||||||
try {
|
|
||||||
passBytes = saltedPass.getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException("UTF-8 not supported!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Md4 md4 = new Md4();
|
Md4 md4 = new Md4();
|
||||||
md4.update(passBytes, 0, passBytes.length);
|
md4.update(passBytes, 0, passBytes.length);
|
||||||
|
|
|
@ -79,13 +79,7 @@ public class MessageDigestPasswordEncoder extends BaseDigestPasswordEncoder {
|
||||||
|
|
||||||
MessageDigest messageDigest = getMessageDigest();
|
MessageDigest messageDigest = getMessageDigest();
|
||||||
|
|
||||||
byte[] digest;
|
byte[] digest = messageDigest.digest(Utf8.encode(saltedPass));
|
||||||
|
|
||||||
try {
|
|
||||||
digest = messageDigest.digest(saltedPass.getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException("UTF-8 not supported!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// "stretch" the encoded value if configured to do so
|
// "stretch" the encoded value if configured to do so
|
||||||
for (int i = 1; i < iterations; i++) {
|
for (int i = 1; i < iterations; i++) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.springframework.security.authentication.encoding;
|
package org.springframework.security.authentication.encoding;
|
||||||
|
|
||||||
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,11 +37,8 @@ class PasswordEncoderUtils {
|
||||||
if(s == null) {
|
if(s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
return s.getBytes("UTF-8");
|
return Utf8.encode(s);
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException("Could not get bytes in UTF-8 format",e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private PasswordEncoderUtils() {}
|
private PasswordEncoderUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.springframework.security.core.token;
|
package org.springframework.security.core.token;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.security.crypto.codec.Base64;
|
import org.springframework.security.crypto.codec.Base64;
|
||||||
import org.springframework.security.crypto.codec.Hex;
|
import org.springframework.security.crypto.codec.Hex;
|
||||||
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public class KeyBasedPersistenceTokenService implements TokenService, Initializi
|
||||||
// Compute key
|
// Compute key
|
||||||
String sha512Hex = Sha512DigestUtils.shaHex(content + ":" + serverSecret);
|
String sha512Hex = Sha512DigestUtils.shaHex(content + ":" + serverSecret);
|
||||||
String keyPayload = content + ":" + sha512Hex;
|
String keyPayload = content + ":" + sha512Hex;
|
||||||
String key = convertToString(Base64.encode(convertToBytes(keyPayload)));
|
String key = Utf8.decode(Base64.encode(Utf8.encode(keyPayload)));
|
||||||
|
|
||||||
return new DefaultToken(key, creationTime, extendedInformation);
|
return new DefaultToken(key, creationTime, extendedInformation);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class KeyBasedPersistenceTokenService implements TokenService, Initializi
|
||||||
if (key == null || "".equals(key)) {
|
if (key == null || "".equals(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] tokens = StringUtils.delimitedListToStringArray(convertToString(Base64.decode(convertToBytes(key))), ":");
|
String[] tokens = StringUtils.delimitedListToStringArray(Utf8.decode(Base64.decode(Utf8.encode(key))), ":");
|
||||||
Assert.isTrue(tokens.length >= 4, "Expected 4 or more tokens but found " + tokens.length);
|
Assert.isTrue(tokens.length >= 4, "Expected 4 or more tokens but found " + tokens.length);
|
||||||
|
|
||||||
long creationTime;
|
long creationTime;
|
||||||
|
@ -109,22 +109,6 @@ public class KeyBasedPersistenceTokenService implements TokenService, Initializi
|
||||||
return new DefaultToken(key, creationTime, extendedInfo.toString());
|
return new DefaultToken(key, creationTime, extendedInfo.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] convertToBytes(String input) {
|
|
||||||
try {
|
|
||||||
return input.getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String convertToString(byte[] bytes) {
|
|
||||||
try {
|
|
||||||
return new String(bytes, "UTF-8");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a pseduo random number (hex encoded)
|
* @return a pseduo random number (hex encoded)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,6 +28,7 @@ import javax.naming.directory.SearchResult;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.springframework.ldap.UncategorizedLdapException;
|
import org.springframework.ldap.UncategorizedLdapException;
|
||||||
import org.springframework.ldap.core.ContextExecutor;
|
import org.springframework.ldap.core.ContextExecutor;
|
||||||
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Luke Taylor
|
* @author Luke Taylor
|
||||||
|
@ -51,12 +52,12 @@ public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTest
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compareOfCorrectByteValueSucceeds() {
|
public void compareOfCorrectByteValueSucceeds() {
|
||||||
assertTrue(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("bobspassword")));
|
assertTrue(template.compare("uid=bob,ou=people", "userPassword", Utf8.encode("bobspassword")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compareOfWrongByteValueFails() {
|
public void compareOfWrongByteValueFails() {
|
||||||
assertFalse(template.compare("uid=bob,ou=people", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue")));
|
assertFalse(template.compare("uid=bob,ou=people", "userPassword", Utf8.encode("wrongvalue")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.springframework.security.ldap;
|
||||||
|
|
||||||
import org.springframework.ldap.core.DirContextAdapter;
|
import org.springframework.ldap.core.DirContextAdapter;
|
||||||
import org.springframework.ldap.core.DistinguishedName;
|
import org.springframework.ldap.core.DistinguishedName;
|
||||||
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -25,7 +26,6 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import javax.naming.Context;
|
import javax.naming.Context;
|
||||||
import javax.naming.NamingEnumeration;
|
import javax.naming.NamingEnumeration;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
@ -123,29 +123,11 @@ public final class LdapUtils {
|
||||||
return baseDn;
|
return baseDn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getUtf8Bytes(String s) {
|
|
||||||
try {
|
|
||||||
return s.getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// Should be impossible since UTF-8 is required by all implementations
|
|
||||||
throw new IllegalStateException("Failed to convert string to UTF-8 bytes. Shouldn't be possible");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getUtf8BytesAsString(byte[] utf8) {
|
|
||||||
try {
|
|
||||||
return new String(utf8, "UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// Should be impossible since UTF-8 is required by all implementations
|
|
||||||
throw new IllegalStateException("Failed to convert string to UTF-8 bytes. Shouldn't be possible");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String convertPasswordToString(Object passObj) {
|
public static String convertPasswordToString(Object passObj) {
|
||||||
Assert.notNull(passObj, "Password object to convert must not be null");
|
Assert.notNull(passObj, "Password object to convert must not be null");
|
||||||
|
|
||||||
if(passObj instanceof byte[]) {
|
if(passObj instanceof byte[]) {
|
||||||
return getUtf8BytesAsString((byte[])passObj);
|
return Utf8.decode((byte[])passObj);
|
||||||
} else if (passObj instanceof String) {
|
} else if (passObj instanceof String) {
|
||||||
return (String)passObj;
|
return (String)passObj;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.springframework.security.authentication.encoding.LdapShaPasswordEncod
|
||||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.ldap.LdapUtils;
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public final class PasswordComparisonAuthenticator extends AbstractLdapAuthentic
|
||||||
}
|
}
|
||||||
|
|
||||||
String encodedPassword = passwordEncoder.encodePassword(password, null);
|
String encodedPassword = passwordEncoder.encodePassword(password, null);
|
||||||
byte[] passwordBytes = LdapUtils.getUtf8Bytes(encodedPassword);
|
byte[] passwordBytes = Utf8.encode(encodedPassword);
|
||||||
|
|
||||||
if (!ldapTemplate.compare(user.getDn().toString(), passwordAttributeName, passwordBytes)) {
|
if (!ldapTemplate.compare(user.getDn().toString(), passwordAttributeName, passwordBytes)) {
|
||||||
throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials",
|
throw new BadCredentialsException(messages.getMessage("PasswordComparisonAuthenticator.badCredentials",
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.security.web.authentication.rememberme;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.crypto.codec.Hex;
|
import org.springframework.security.crypto.codec.Hex;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.crypto.codec.Utf8;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -222,9 +223,6 @@ public class TokenBasedRememberMeServices extends AbstractRememberMeServices {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant time comparison to prevent against timing attacks.
|
* Constant time comparison to prevent against timing attacks.
|
||||||
* @param expected
|
|
||||||
* @param actual
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private static boolean equals(String expected, String actual) {
|
private static boolean equals(String expected, String actual) {
|
||||||
byte[] expectedBytes = bytesUtf8(expected);
|
byte[] expectedBytes = bytesUtf8(expected);
|
||||||
|
@ -241,13 +239,9 @@ public class TokenBasedRememberMeServices extends AbstractRememberMeServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] bytesUtf8(String s) {
|
private static byte[] bytesUtf8(String s) {
|
||||||
if(s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return Utf8.encode(s);
|
||||||
return s.getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException("Could not get bytes in UTF-8 format",e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue