У меня есть приложение для Android, которое является «сервером» в дизайне клиент / сервер. В приложении мне нужно вычислить хеш MD5 для набора строк и вернуть результат клиенту, чтобы продолжить разговор между ними. Мой код для этого был собран из многочисленных примеров. Алгоритм вычисления хэша (не разработанный мной) выглядит так:
- Преобразование строки в массив байтов
- Используйте класс MessageDigest для генерации хеша
- Преобразовать полученный хеш обратно в строку
Похоже, что хеш верен для 99% моих клиентов. Один из клиентов, увидевший неправильный хэш, работает с немецким языком, и это начало вызывать у меня вопрос, может ли язык влиять на результат, который я получаю. Это код для создания байтового массива из строки:
public static byte[] hexStringToByteArray(String s)
{
byte[] data = null;
if(s.length() % 2 != 0)
{
s = "0" + s;
}
int len = s.length();
data = new byte[len / 2];
for (int i = 0; i < len; i += 2)
{
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
А вот текущая версия функции хеширования:
public static String hashDataAsString(String dataToHash)
{
MessageDigest messageDigest;
try
{
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
byte[] data = hexStringToByteArray(dataToHash);
messageDigest.update(data);
final byte[] resultByte = messageDigest.digest();
return new String(Hex.encodeHex(resultByte));
}
catch(NoSuchAlgorithmException e)
{
throw new RuntimeException("Failed to hash data values", e);
}
}
Я использую функцию Hex.encodeHex от Apache Commons .
Я пытался переключить свой телефон на немецкий язык, но мои модульные тесты все еще дают правильный результат хеширования. Этот клиент использует стоковую версию Froyo, что исключает риск того, что пользовательское ПЗУ будет здесь ошибочным. Я также нашел эту альтернативу для преобразования из байтов в строку:
public static String MD5_Hash(String s) {
MessageDigest m = null;
try {
m = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//m.update(s.getBytes(),0,s.length());
byte [] data = hexStringToByteArray(s);
m.update(data, 0, data.length);
String hash = new BigInteger(1, m.digest()).toString(16);
return hash;
}
В моих модульных тестах это дает тот же ответ. Может ли BigInteger быть более безопасной альтернативой для использования здесь?