Как правильно хешировать строку в Java: SHA1 и MessageDigest

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы преобразовать строку в SHA-1 хеш в Java, воспользуйтесь классом MessageDigest. Вот подходящий пример кода:

Java
Скопировать код
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1Hasher {
    public static String toSHA1(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] result = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : result) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Для получения SHA-1 хеша строки, вызовите метод toSHA1("text"). Учтите, что исключение NoSuchAlgorithmException следует адекватно обработать.

Кинга Идем в IT: пошаговый план для смены профессии

Борьба с кодировками: UTF-8 или ничего

Применение уместной кодировки символов является критически важным. Рекомендуем в явном виде указывать кодировку UTF-8:

Java
Скопировать код
byte[] result = md.digest(input.getBytes(StandardCharsets.UTF_8));

Использование StandardCharsets.UTF_8 предотвратит возможные проблемы с кодировкой в будущем.

Сторонам шестнадцатеричной системы, уступите дорогу Base64

Base64 – это более компактный способ кодировки хешей. Он экономит пространство и повышает читаемость, особенно при использовании библиотеки Apache Commons Codec:

Java
Скопировать код
import org.apache.commons.codec.binary.Base64;

String sha1Base64 = new String(Base64.encodeBase64(result), StandardCharsets.UTF_8);

Ещё одним полезным инструментом является DigestUtils, облегчающий процесс преобразований:

Java
Скопировать код
import org.apache.commons.codec.digest.DigestUtils;

public static String toSHA1Hex(String input) {
    return DigestUtils.sha1Hex(input.getBytes(StandardCharsets.UTF_8));
}

Для сторонников ясности и лаконичности, Guava предлагает свою утилиту Hashing:

Java
Скопировать код
import com.google.common.hash.Hashing;

public static String toSHA1Guava(String input) {
    return Hashing.sha1().hashString(input, StandardCharsets.UTF_8).toString();
}

Работая с криптографией, следите за безопасностью и придерживайтесь наилучших практик.

Визуализация

Вы можете вообразить процесс преобразования строки Java в хеш SHA1 как превращение яйца в курицу:

Markdown
Скопировать код
До: 🥚 (начальная строка Java)
Процесс: 🐣➡️🐥➡️🐔 (алгоритм SHA1)
После: 🍗 (уникальный, необратимый хеш SHA1)

Обратить хеширование SHA-1 невозможно:

Markdown
Скопировать код
Обратное преобразование: 🍗 ➡️ 🚫 ➡️ 🥚 (SHA1 необратим)

Каждый хеш является уникальным:

Markdown
Скопировать код
Уникальность: "HelloWorld" ➡️ 🍗 не равно "hello world" ➡️ 🍗

Остерегайтесь подводных камней!

Борьба против (не)безопасности

SHA1 подвержен атакам на коллизии. Для обеспечения улучшенной безопасности используйте SHA-256 или SHA-3.

Не споткнитесь о неожиданности

Не забывайте сбрасывать экземпляр MessageDigest перед новым хешированием:

Java
Скопировать код
md.reset();

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

Java
Скопировать код
try (Formatter formatter = new Formatter()) {
    for (byte b : result) {
        formatter.format("%02x", b);
    }
    return formatter.toString();
}

Идеальная библиотека для задачи

При выборе библиотеки для работы с хешированием, рассмотрите Apache Commons Codec, Bouncy Castle или Google's Guava.

Избегайте непонятных символов, придерживайтесь кодировки

Всегда указывайте кодировку при преобразовании массива байтов в строку, чтобы избежать ошибок:

Java
Скопировать код
String sha1String = new String(result, StandardCharsets.UTF_8);

Полезные материалы

  1. MessageDigest (Java SE 17 & JDK 17) — официальная документация Java для класса MessageDigest.
  2. Java String to SHA1 – Stack Overflow — обсуждения и решения для преобразования строк в SHA1.
  3. Java Cryptography Architecture (JCA) Reference Guide — справочник по криптографии Java.
  4. Codec – Home — Apache Commons Codec, библиотека для работы с хешированием.
  5. Quick Programming Tips — советы по созданию SHA1 хеша в Java.
  6. GitHub – apache/commons-codec: Apache Commons Codec — исходный код Apache Commons Codec, полезный для практики.