Когда я вычисляю в Java SHA-256 строки со следующим методом
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest("password".getBytes());
StringBuffer sb = new StringBuffer();
for(byte b : hash) {
sb.append(Integer.toHexString(b & 0xff));
}
System.out.println(sb.toString());
}
Я добираюсь:
5e884898da2847151d0e56f8dc6292773603dd6aabbdd62a11ef721d1542d8
на командной строке я делаю следующее (мне нужно -n
не добавить новую строку):
echo -n "password" | sha256sum
и доберитесь
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
если мы сравниваем их более тесно, я нахожу 2 тонких различия
5e884898da2847151d0e56f8dc6292773603dd6aabbdd62a11ef721d1542d8
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
или:
5e884898da28 47151d0e56f8dc6292773603d d6aabbdd62a11ef721d1542d8
5e884898da28 0 47151d0e56f8dc6292773603d 0 d6aabbdd62a11ef721d1542d8
Какой из этих 2 корректен здесь?
Результат: Оба всего лишь, я был неправ...
зафиксированный это при помощи:
StringBuffer sb = new StringBuffer();
for(byte b : hash) {
sb.append(String.format("%02x", b));
}
Спасибо!
Выскажу разумное предположение: обе программы выдают один и тот же дайджест, но в вашем Java-коде, который выводит результат byte[]
в виде шестнадцатеричной строки, вы выводите маленькие значения байтов (меньше 16) без ведущего 0. Поэтому байт со значением "0x0d" записывается как "d", а не "0d".
Они оба правы - виноват ваш код Java, потому что он не выводит ведущий 0 для шестнадцатеричного значения меньше 0x10.
Причина - toHexString
. Похоже, что он выводит 6
для значения 6, тогда как sha256sum
выводит 06
. В документации Java для Integer.toHexString ()
указано:
Это значение преобразуется в строку цифр ASCII в шестнадцатеричном формате (с основанием 16) без дополнительных начальных нулей.
Остальные нули в строке не затрагиваются, поскольку они являются второй половиной байтов (например, 30
).
Один из способов исправить это - изменить:
for(byte b : hash) {
sb.append(Integer.toHexString(b & 0xff));
}
на:
for(byte b : hash) {
if (b < 16) sb.append("0");
sb.append(Integer.toHexString(b & 0xff));
}
Сумма, генерируемая sha256sum, кажется правильной. Ваша реализация, похоже, отбрасывает эти два нуля.