Строка Java в формате SHA1



Я пытаюсь сделать простой конвертер строк в 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"? Или я делаю это совершенно неправильно?



Спасибо большое!

696   11  

11 ответов:

обновление
Вы можете использовать Apache Commons Codec (версия 1.7+), чтобы сделать эту работу для вас.

DigestUtils.sha1Hex(stringToConvertToSHexRepresentation)

спасибо @Джон Онстотт за это предложение.


Ответ
Преобразуйте свой массив байтов в шестнадцатеричную строку. Real's How to tells you how.

return byteArrayToHexString(md.digest(convertme))

и (скопировано из Real's How To)

public static String byteArrayToHexString(byte[] b) {
  String result = "";
  for (int i=0; i < b.length; i++) {
    result +=
          Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
  }
  return result;
}

кстати, вы можете получить более компактный представление с использованием Base64. Apache Commons Codec API 1.4, это хорошая утилита, чтобы забрать всю боль. см. здесь

Это мое решение преобразования строки в sha1. Он хорошо работает в моем приложении для Android:

private static String encryptPassword(String password)
{
    String sha1 = "";
    try
    {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        sha1 = byteToHex(crypt.digest());
    }
    catch(NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch(UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    return sha1;
}

private static String byteToHex(final byte[] hash)
{
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
        formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
}

С помощью класс хеширования гуавы:

Hashing.sha1().hashString( "password", Charsets.UTF_8 ).toString()

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 (или другой кодировки, которая может представлять каждый символ Юникода) является самым безопасным выбором здесь.

просто используйте библиотеку кодеков Apache commons. У них есть служебный класс под названием DigestUtils

Не нужно вдаваться в подробности.

Это простое решение, которое может быть использовано при преобразовании строки в шестнадцатеричный формат:

private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {

    MessageDigest crypt = MessageDigest.getInstance("SHA-1");
    crypt.reset();
    crypt.update(password.getBytes("UTF-8"));

    return new BigInteger(1, crypt.digest()).toString(16);
}

Как упоминалось ранее, используйте кодек apache commons. Это также рекомендуется весенними парнями (см. DigestUtils in Spring doc). Например:

DigestUtils.sha1Hex(b);

определенно не будет использовать самый рейтинговый ответ здесь.

это не печать правильно, потому что вам нужно использовать кодировку Base64. С Java 8 вы можете кодировать с помощью Base64 класс шифратора.

public static String toSHA1(byte[] convertme) {
    md = MessageDigest.getInstance("SHA-1");
    return Base64.getEncoder().encodeToString((md.digest(convertme));
}

результат

это даст вам ожидаемый результат 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

причина, по которой это не работает, заключается в том, что при вызове String(md.digest(convertme)), вы говорите Java интерпретировать последовательность зашифрованных байтов как строку. То, что вы хотите, чтобы преобразовать байты в шестнадцатеричные символы.

преобразование массива байтов в шестнадцатеричную строку.

public static String toSHA1(byte[] convertme) {
    final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-1");
    }
    catch(NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    byte[] buf = md.digest(convertme);
    char[] chars = new char[2 * buf.length];
    for (int i = 0; i < buf.length; ++i) {
        chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
        chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
    }
    return new String(chars);
}

база 64 представление SHA1 хэш:

String hashedVal = Base64.getEncoder().encodeToString(DigestUtils.sha1(stringValue.getBytes(Charset.forName("UTF-8"))));

Comments

    Ничего не найдено.