MessageDigest.getInstance: примеры (JAVA)
MessageDigest.getInstance(String algorithm): MessageDigestОписание метода MessageDigest.getInstance
Метод MessageDigest.getInstance из пакета java.security возвращает объект типа java.security.MessageDigest, реализующий указанный алгоритм хеширования. Основное назначение - вычисление криптографических дайджестов (хешей) для данных.
Сигнатуры метода:
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmExceptionpublic static MessageDigest getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderExceptionpublic static MessageDigest getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException
Аргументы и их значение:
algorithm- наименование алгоритма хеширования в виде строки, например"MD5","SHA-1","SHA-256","SHA3-256". Значение чувствительно к регистру в зависимости от провайдера, обычно регистр не имеет значения для стандартных поставщиков.provider(String) - имя поставщика безопасности, зарегистрированного вjava.security.Security, например"SUN"или"BC"для BouncyCastle. Если указан, попытка будет использовать именно этого поставщика.provider(Provider) - экземплярjava.security.Provider, позволяющий получить реализацию от конкретного объекта поставщика.
Возвращаемое значение:
- Экземпляр
MessageDigest, поддерживающий указанный алгоритм. С его помощью доступны методыupdate,digest,reset,clone(если поддерживается) и другие.
Исключения и поведение при ошибках:
NoSuchAlgorithmException- алгоритм не найден у доступных поставщиков.NoSuchProviderException- указанный поставщик по имени не найден (сигнатура с именем поставщика).- Возможны
NullPointerExceptionпри передачеnullв качестве алгоритма.
Особенности:
- Экземпляры
MessageDigestне являются потокобезопасными. Для параллельного использования требуется синхронизация или отдельные экземпляры. - Поддерживаемые алгоритмы зависят от установленных провайдеров и версии JDK.
Примеры основных вариантов использования
Примеры иллюстрируют различные способы получения экземпляра MessageDigest и получение хеша строки "hello".
MD5 через стандартный вызов:
import java.security.MessageDigest;
import java.util.HexFormat;
public class Md5Example {
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest("hello".getBytes(java.nio.charset.StandardCharsets.UTF_8));
System.out.println(HexFormat.of().formatHex(digest));
}
}
5d41402abc4b2a76b9719d911017c592
SHA-256 и использование update:
import java.security.MessageDigest;
import java.util.HexFormat;
public class Sha256Example {
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update("he".getBytes());
md.update("llo".getBytes());
byte[] digest = md.digest();
System.out.println(HexFormat.of().formatHex(digest));
}
}
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Запрос реализации у конкретного провайдера (имя провайдера может отсутствовать - тогда будет NoSuchProviderException):
import java.security.MessageDigest;
public class ProviderExample {
public static void main(String[] args) throws Exception {
// Если провайдера с таким именем нет, будет NoSuchProviderException
MessageDigest md = MessageDigest.getInstance("SHA-256", "SUN");
System.out.println(md.getAlgorithm() + " from " + md.getProvider().getName());
}
}
SHA-256 from SUN
Похожие механизмы в Java
Несколько альтернатив и смежных API в экосистеме Java:
- javax.crypto.Mac - для HMAC и других ключевых функций хеширования. Используется, когда требуется ключированная защита целостности.
- java.security.Signature - для цифровой подписи, если требуется не только хеш, но и асимметричная подпись.
- java.util.zip.CRC32 - не криптографический контроль целостности, быстрый и простой, но не предназначен для безопасности.
- java.security.DigestInputStream - обертка для потокового вычисления дайджеста при чтении данных.
- MessageDigest.isEqual - метод для сравнения хешей, реализующий безопасное сравнение против атак временного анализа.
Выбор зависит от цели: для неподписанных хешей подходит MessageDigest, для ключированных MAC - Mac, для подписи - Signature, для контрольных сумм без криптостойкости - CRC32.
Аналоги в других языках и их отличия
Краткие примеры по языкам; входная строка - "hello"; пример на SHA-256, где это уместно.
PHP (функция hash):
<?
echo hash('sha256', 'hello');
?>
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
JavaScript (Node.js):
const { createHash } = require('crypto');
console.log(createHash('sha256').update('hello').digest('hex'));
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Python (hashlib):
import hashlib
print(hashlib.sha256(b'hello').hexdigest())
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SQL (MySQL):
SELECT SHA2('hello', 256);
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
C# (.NET):
using System;
using System.Security.Cryptography;
using System.Text;
class Program {
static void Main() {
using var sha = SHA256.Create();
var hash = sha.ComputeHash(Encoding.UTF8.GetBytes("hello"));
Console.WriteLine(BitConverter.ToString(hash).Replace("-", "").ToLower());
}
}
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Go (crypto/sha256):
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
h := sha256.Sum256([]byte("hello"))
fmt.Println(hex.EncodeToString(h[:]))
}
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Lua (с использованием luaossl или openssl):
-- пример с luaossl
local digest = require('openssl').digest
print(digest.new('sha256'):final('hello'):tohex())
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Отличия от Java: названия алгоритмов и API различаются, встроенные провайдеры и доступность алгоритмов зависят от среды. В Java используется концепция провайдеров, чего нет в большинстве простых реализаций других языков.
Типичные ошибки и примеры
Ниже наиболее распространенные ошибки при использовании MessageDigest.getInstance.
1) Неверное имя алгоритма - NoSuchAlgorithmException:
import java.security.MessageDigest;
public class BadAlgo {
public static void main(String[] args) throws Exception {
MessageDigest.getInstance("SHA-999");
}
}
Exception in thread "main" java.security.NoSuchAlgorithmException: SHA-999 MessageDigest not available
2) Указан несуществующий поставщик - NoSuchProviderException:
import java.security.MessageDigest;
public class BadProvider {
public static void main(String[] args) throws Exception {
MessageDigest.getInstance("SHA-256", "NO_SUCH_PROVIDER");
}
}
Exception in thread "main" java.security.NoSuchProviderException: no such provider: NO_SUCH_PROVIDER
3) NullPointerException при передаче null в качестве алгоритма:
MessageDigest.getInstance(null);
Exception in thread "main" java.lang.NullPointerException
4) Проблемы многопоточного доступа: использование одного экземпляра без синхронизации приводит к некорректным результатам. Пример неправильного параллельного использования может не выдавать исключение, а привести к неверному хешу. Решения: отдельные экземпляры для потоков или синхронизация, либо использование clone() если поддерживается.
5) Неправильная работа при повторном вызове digest без reset: при последовательных вызовах без reset предыдущие данные учитываются, что может вести к неожиданным результатам.
Изменения и история поддержки алгоритмов
Ключевые изменения, затрагивающие MessageDigest.getInstance:
- Включение SHA-3 (например, SHA3-256) в стандартную поставку Java началось с Java 9; доступность зависит от версии JDK и провайдеров.
- Списки поддерживаемых алгоритмов эволюционировали: устаревшие алгоритмы (например, MD2) во многих дистрибутивах получают ограничение или удаляются по соображениям безопасности.
- Возможность подключения сторонних провайдеров (например, BouncyCastle) остается основным способом расширения набора алгоритмов.
Сам метод API в последних релизах JVM существенных изменений не претерпел, изменения касались прежде всего поставщиков и доступных алгоритмов.
Расширенные и редкие сценарии использования
Несколько более сложных примеров с пояснениями.
1) Вычисление дайджеста большого файла с DigestInputStream:
import java.io.FileInputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.HexFormat;
public class FileDigest {
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
try (DigestInputStream dis = new DigestInputStream(new FileInputStream("/path/to/file.bin"), md)) {
byte[] buffer = new byte[8192];
while (dis.read(buffer) != -1) { }
}
System.out.println(HexFormat.of().formatHex(md.digest()));
}
}
(здесь будет SHA-256 хеш указанного файла)
2) Параллельные вычисления через clone(): если реализация поддерживает клонирование, это ускоряет работу при одинаковом начальном состоянии:
MessageDigest md = MessageDigest.getInstance("SHA-256");
MessageDigest md1 = (MessageDigest) md.clone();
MessageDigest md2 = (MessageDigest) md.clone();
md1.update("part1".getBytes());
md2.update("part2".getBytes());
byte[] d1 = md1.digest();
byte[] d2 = md2.digest();
(два отдельных дайджеста для разных частей)
3) Использование BouncyCastle как провайдера для дополнительных алгоритмов:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.MessageDigest;
import java.security.Security;
public class BcExample {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
MessageDigest md = MessageDigest.getInstance("SHA3-256", "BC");
byte[] d = md.digest("hello".getBytes());
System.out.println(java.util.HexFormat.of().formatHex(d));
}
}
(SHA3-256 хеш строки "hello")
4) Константно-временное сравнение хешей:
byte[] a = ...;
byte[] b = ...;
boolean equal = MessageDigest.isEqual(a, b);
true или false без уязвимости по времени выполнения
5) Создание собственного провайдера: при наличии специфичных требований алгоритмов возможно написать и зарегистрировать собственную реализацию Provider, после чего MessageDigest.getInstance сможет возвращать реализацию от этого провайдера.
джава MessageDigest.getInstance function comments
- джава MessageDigest.getInstance - аргументы и возвращаемое значение
- Функция java MessageDigest.getInstance - описание
- MessageDigest.getInstance - примеры
- MessageDigest.getInstance - похожие методы на java
- MessageDigest.getInstance на javascript, c#, python, php
- MessageDigest.getInstance изменения java
- Примеры MessageDigest.getInstance на джава