1. Обзор
SHA (Secure Hash Algorithm) — одна из популярных криптографических хеш-функций. Криптографический хэш можно использовать для подписи текста или файла данных.
В этом руководстве давайте посмотрим, как мы можем выполнять операции хеширования SHA-256 и SHA3-256, используя различные библиотеки Java.
Алгоритм SHA-256 генерирует почти уникальный 256-битный (32-байтовый) хэш фиксированного размера. Это односторонняя функция, поэтому результат не может быть расшифрован обратно в исходное значение.
В настоящее время хеширование SHA-2 широко используется, так как считается самым безопасным алгоритмом хеширования в криптографической сфере.
SHA-3 — это новейший стандарт безопасного хеширования после SHA-2. По сравнению с SHA-2, SHA-3 предлагает другой подход к созданию уникального одностороннего хэша, и он может быть намного быстрее на некоторых аппаратных реализациях. Подобно SHA-256, SHA3-256 — это 256-битный алгоритм фиксированной длины в SHA-3.
NIST выпустил SHA-3 в 2015 году, поэтому на данный момент существует не так много библиотек SHA-3, как SHA-2. Только в JDK 9 алгоритмы SHA-3 были доступны во встроенных поставщиках по умолчанию.
Теперь начнем с SHA-256.
2. Класс MessageDigest
в Java
Java предоставляет встроенный класс MessageDigest
для хеширования SHA-256:
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
Однако здесь мы должны использовать специальный преобразователь байтов в шестнадцатеричный, чтобы получить хешированное значение в шестнадцатеричном формате:
private static String bytesToHex(byte[] hash) {
StringBuilder hexString = new StringBuilder(2 * hash.length);
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if(hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
Мы должны знать, что MessageDigest не является потокобезопасным. Следовательно, мы должны использовать новый экземпляр для каждого потока.
3. Библиотека гуавы
Библиотека Google Guava также предоставляет служебный класс для хеширования.
Во-первых, давайте определим зависимость:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
Далее, вот как мы можем использовать Guava для хэширования строки:
String sha256hex = Hashing.sha256()
.hashString(originalString, StandardCharsets.UTF_8)
.toString();
4. Кодеки Apache Commons
Точно так же мы можем использовать кодеки Apache Commons:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
Вот служебный класс DigestUtils
, который поддерживает хеширование SHA-256:
String sha256hex = DigestUtils.sha256Hex(originalString);
5. Библиотека Надувного замка
5.1. Зависимость от Maven
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
5.2. Хеширование с использованием библиотеки Bouncy Castle
API Bouncy Castle предоставляет служебный класс для преобразования шестнадцатеричных данных в байты и обратно.
Однако сначала нам нужно заполнить дайджест с помощью встроенного Java API:
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha256hex = new String(Hex.encode(hash));
6. ША3-256
Теперь продолжим с SHA3-256. Хеширование SHA3-256 в Java мало чем отличается от SHA-256.
6.1. Класс MessageDigest
в Java
Начиная с JDK 9 , мы можем просто использовать встроенный алгоритм SHA3-256:
final MessageDigest digest = MessageDigest.getInstance("SHA3-256");
final byte[] hashbytes = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(hashbytes);
6.2. Кодеки Apache Commons
Apache Commons Codecs предоставляет удобную оболочку DigestUtils
для класса MessageDigest .
Эта библиотека начала поддерживать SHA3-256 с версии 1.11 , а также требует JDK 9+ :
String sha3Hex = new DigestUtils("SHA3-256").digestAsHex(originalString);
6.3. Кекчак-256
Keccak-256 — еще один популярный алгоритм хеширования SHA3-256. В настоящее время он служит альтернативой стандартному SHA3-256. Keccak-256 обеспечивает тот же уровень безопасности, что и стандартный SHA3-256, и отличается от SHA3-256 только правилом заполнения. Он использовался в нескольких блокчейн-проектах, таких как Monero .
Опять же, нам нужно импортировать библиотеку Bouncy Castle, чтобы использовать хеширование Keccak-256:
Security.addProvider(new BouncyCastleProvider());
final MessageDigest digest = MessageDigest.getInstance("Keccak-256");
final byte[] encodedhash = digest.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = bytesToHex(encodedhash);
Мы также можем использовать API Bouncy Castle для хеширования:
Keccak.Digest256 digest256 = new Keccak.Digest256();
byte[] hashbytes = digest256.digest(
originalString.getBytes(StandardCharsets.UTF_8));
String sha3Hex = new String(Hex.encode(hashbytes));
7. Заключение
В этой быстрой статье мы рассмотрели несколько способов реализации хеширования SHA-256 и SHA3-256 в Java с использованием как встроенных, так и сторонних библиотек.
Исходный код примеров можно найти в проекте GitHub .