Refactoring to use Utf8 encoder instead of String.getBytes("UTF-8").

This commit is contained in:
Luke Taylor 2011-06-14 18:34:48 +01:00
parent 361b77685d
commit 571bfc4869
9 changed files with 21 additions and 75 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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++) {

View File

@ -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() {}
} }

View File

@ -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)
*/ */

View File

@ -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

View File

@ -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 {

View File

@ -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",

View File

@ -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);
}
} }
} }