Я пытаюсь сделать простой конвертер строки в SHA1 в Java, и это то, что у меня есть ...
public static String toSHA1(byte[] convertme) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
}
catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new String(md.digest(convertme));
}
Когда я передаю его toSHA1("password".getBytes())
, я понимаю, [�a�ɹ??�%l�3~��.
что это, вероятно, простое исправление кодировки, такое как UTF-8, но кто-то может сказать мне, что я должен сделать, чтобы получить то, что я хочу 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
? Или я делаю это совершенно неправильно?
SHA1
без дефиса, не знаю, будет ли это иметь значение.getBytes()
, например usetoSHA1("password".getBytes("UTF-8"))
Ответы:
ОБНОВЛЕНИЕ
Вы можете использовать кодек Apache Commons (версия 1.7+), чтобы сделать эту работу за вас.
Спасибо @ Jon Onstott за это предложение.
Старый ответ
Преобразование массива байтов в шестнадцатеричную строку. Real's How To рассказывает вам, как .
и (скопировано из Real's How To)
Кстати, вы можете получить более компактное представление с помощью Base64. Apache Commons Codec API 1.4 , имеет эту полезную утилиту, чтобы убрать всю боль. обратитесь сюда
источник
DigestUtils.sha1Hex("my string")
вместо того, чтобы заново изобретать колесо (хотя интересно знать, как конвертировать в гекс вручную)?Это мое решение для преобразования строки в sha1. Это хорошо работает в моем приложении для Android:
источник
encryptPassword("test")
иecho test|sha1sum
в терминале Linux вывести тот же результат? Они неecho test
, вывод, включая разрыв строки, будет передан по конвейеруsha1sum
. Если вы хотите хэшировать простую строку без завершающего переноса строки, вы можете использоватьecho -n test | sha1sum
.-n
Параметр позволяетecho
опустить разрыв строки.encryptPassword()
звуки похожи на те, которые используются для хранения аутентификационных данных. Обратите внимание, что ваше кодирование уязвимо для атак по словарю, так как не применяется заполнение. Проверьте вашу среду безопасности, является ли это проблемой для вашего приложения!Использование класса Guava Hashing :
источник
SHA-1 (и все другие алгоритмы хеширования) возвращают двоичные данные. Это означает, что (на Java) они производят
byte[]
. Этотbyte
массив не представляет никаких конкретных символов, а это значит, что вы не можете просто превратить его в то,String
что делали.Если вам нужно
String
, то вы должны отформатироватьbyte[]
это так, чтобы это можно было представить какString
(иначе, просто оставьте все как естьbyte[]
).Два обычных способа представления произвольных
byte[]
символов для печати - это BASE64 или простые шестнадцатеричные строки (т.е.byte
из двух шестнадцатеричных цифр). Похоже, вы пытаетесь создать шестнадцатеричную строку.Есть и еще один подводный камень: если вы хотите получить SHA-1 Java
String
, то вам нужно преобразоватьString
его вbyte[]
первое (поскольку вход SHA-1 также являетсяbyte[]
). Если вы просто используете,myString.getBytes()
как вы показали, то он будет использовать кодировку платформы по умолчанию и, как таковой, будет зависеть от среды, в которой вы его запускаете (например, он может возвращать разные данные в зависимости от настроек языка / локали вашей ОС).Лучшее решение указать кодировку для использования для
String
-До-byte[]
преобразования , как это:myString.getBytes("UTF-8")
. Выбор UTF-8 (или другой кодировки, которая может представлять каждый символ Unicode) - самый безопасный выбор здесь.источник
Это простое решение, которое можно использовать при преобразовании строки в шестнадцатеричный формат:
источник
Просто используйте библиотеку кодеков Apache Commons. У них есть служебный класс, называемый DigestUtils
Не нужно вдаваться в подробности.
источник
String result = DigestUtils.sha1Hex("An input string")
Как упоминалось ранее, используйте кодек Apache Commons. Это также рекомендуется парнями из Spring (см. DigestUtils в Spring doc). Например:
Определенно не буду использовать здесь самый лучший ответ.
источник
Печатается неправильно, потому что вам нужно использовать кодировку Base64. С Java 8 вы можете кодировать, используя класс кодировщика Base64 .
результат
Это даст вам ожидаемый результат
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
источник
Дайджест сообщения (хеш) - это байт [] в байте [] из
Дайджест сообщения определяется как функция, которая принимает необработанный байтовый массив и возвращает необработанный байтовый массив (он же
byte[]
). Например, SHA-1 (Secure Hash Algorithm 1) имеет размер дайджеста 160 бит или 20 байт. Необработанные байтовые массивы обычно не могут быть интерпретированы как кодировки символов, такие как UTF-8 , потому что не каждый байт в каждом порядке является законным кодированием. Так что конвертируем их вString
:может создавать недопустимые последовательности или иметь указатели кода на неопределенные отображения Unicode :
Двоичное в текстовое кодирование
Для этого используется двоичное кодирование текста . Для хэшей чаще всего используется кодировка HEX или Base16 . По существу, байт может иметь значение от
0
до255
(или-128
со127
знаком), которое эквивалентно шестнадцатеричному представлению0x00
-0xFF
. Поэтому hex будет удваивать требуемую длину вывода, что означает, что 20-байтовый вывод создаст строку длиной в 40 символов, например:Обратите внимание, что не требуется использовать шестнадцатеричное кодирование. Вы также можете использовать что-то вроде base64 . Шестнадцатеричный кодекс часто предпочитается, потому что он легче читается людьми и имеет определенную выходную длину без необходимости заполнения.
Вы можете преобразовать байтовый массив в шестнадцатеричный код только с помощью функции JDK:
Однако обратите внимание, что этот
BigInteger
массив байтов будет интерпретироваться как число, а не как строка байтов. Это означает, что начальные нули не будут выводиться, а результирующая строка может быть короче 40 символов.Использование библиотек для кодирования в HEX
Теперь вы можете скопировать и вставить непроверенный метод преобразования байтов в шестнадцатеричный код из Stack Overflow или использовать массивные зависимости, такие как Guava .
Чтобы получить решение для большинства проблем, связанных с байтами, я реализовал утилиту для обработки этих случаев: bytes-java (Github)
Для преобразования вашего байта массива дайджеста сообщения вы можете просто сделать
или вы можете просто использовать встроенную функцию хеширования
источник
Base 64 Представление
SHA1
хэша:источник
Причина, по которой это не работает, заключается в том, что когда вы вызываете
String(md.digest(convertme))
, вы говорите Java интерпретировать последовательность зашифрованных байтов как строку. Вам нужно преобразовать байты в шестнадцатеричные символы.источник
Преобразовать байтовый массив в шестнадцатеричную строку.
источник