Дайджест повідомлень (хеш) - байт [] у байті []
Дайджест повідомлень визначається як функція, яка приймає необроблений байтовий масив і повертає необроблений масив байтів (ака byte[]
). Наприклад, SHA-1 (алгоритм безпечного хешу 1) має дайджест розміром 160 біт або 20 байт. Сировинні байтові масиви зазвичай не можна інтерпретувати як кодування символів, як UTF-8 , тому що не кожен байт у кожному порядку є законним кодування. Тож перетворення їх у a за String
допомогою:
new String(md.digest(subject), StandardCharsets.UTF_8)
може створити кілька незаконних послідовностей або мати покажчики коду на невизначені відображення Unicode :
[�a�ɹ??�%l�3~��.
Бінарне кодування тексту
Для цього використовується кодування бінарного тексту . З хешами найбільше використовується кодування HEX або Base16 . В основному байт може мати значення від 0
до 255
(або -128
на 127
підпис) , яке еквівалентно HEX поданні 0x00
- 0xFF
. Тому шістнадцятковий вдвічі перевищить необхідну довжину виводу, це означає, що 20-байтовий вихід створить шістнадцяткову шістнадцяткову рядок, наприклад:
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
Зауважте, що не потрібно використовувати шістнадцяткове кодування. Ви також можете використовувати щось на зразок base64 . Шестигранну часто надають перевагу, оскільки вона легше читається людиною і має визначену довжину виходу без необхідності прокладки.
Ви можете перетворити масив байтів у шістнадцятковий лише за допомогою функціональності JDK:
new BigInteger(1, token).toString(16)
Однак зауважте, що BigInteger
інтерпретувати заданий масив байтів буде як число, а не як рядок байтів. Це означає, що провідні нулі не виводяться, і результуюча рядок може бути коротшою, ніж 40 символів.
Використання бібліотек для кодування до HEX
Тепер ви можете скопіювати і вставити неперевірений байт-шістнадцятковий метод із переповнення стека або використовувати масивні залежності, такі як Guava .
Щоб мати рішення для більшості проблем, пов’язаних з байтами, я застосував утиліту для обробки таких випадків: bytes-java (Github)
Щоб перетворити масив байтів дайджестів повідомлень, ви могли просто зробити
String hex = Bytes.wrap(md.digest(subject)).encodeHex();
або ви можете просто використовувати вбудовану функцію хешу
String hex = Bytes.from(subject).hashSha1().encodeHex();
SHA1
без дефісу, не знаю, чи це змінить значення.