Полный список MessageDigest, доступный в JDK

Я искал высоко и низко для этого, но я не могу получить прямой ответ.

В Java доступные MessageDigests определяются с помощью тех поставщиков безопасности, которые вы настроили/установили. Но при условии, что только обычная установка JDK8 (1.8.0_11 в моем случае), какой список доступных хэш-алгоритмов? Из примеров в документах очевидны MD5, SHA1 и SHA-256, но я не могу получить полный, авторитетный список.

Имеет ли этот список, или как мне узнать, какая именно установка?

Ответ 1

В дополнение к ответу JB, я хотел бы предложить решение, которое запрашивает время выполнения для доступных алгоритмов. Разумеется, этот метод легко преобразуется в один для Cipher, SecureRandom, Mac, KeyAgreement, KeyFactory или любого другого типа алгоритма.

программа

import java.security.MessageDigest;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class ShowHashAlgorithms {

    private static final void showHashAlgorithms(Provider prov, Class<?> typeClass) {
        String type = typeClass.getSimpleName();

        List<Service> algos = new ArrayList<>();

        Set<Service> services = prov.getServices();
        for (Service service : services) {
            if (service.getType().equalsIgnoreCase(type)) {
                algos.add(service);
            }
        }

        if (!algos.isEmpty()) {
            System.out.printf(" --- Provider %s, version %.2f --- %n", prov.getName(), prov.getVersion());
            for (Service service : algos) {
                String algo = service.getAlgorithm();
                System.out.printf("Algorithm name: \"%s\"%n", algo);


            }
        }

        // --- find aliases (inefficiently)
        Set<Object> keys = prov.keySet();
        for (Object key : keys) {
            final String prefix = "Alg.Alias." + type + ".";
            if (key.toString().startsWith(prefix)) {
                String value = prov.get(key.toString()).toString();
                System.out.printf("Alias: \"%s\" -> \"%s\"%n",
                        key.toString().substring(prefix.length()),
                        value);
            }
        }
    }

    public static void main(String[] args) {
        Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            showHashAlgorithms(provider, MessageDigest.class);
        }
    }
}

Выход поставщика услуг Sun

Этот код будет генерировать следующий результат для Java 1.8. Обратите внимание, что из-за какой-то старой ошибки поставщиков API версия поставщика присутствует только в виде double. Из-за этого невозможно отличить версию 1.80 или версию 1.8.0.

Алиасы ниже фактических реализаций. Некоторые из этих псевдонимов являются Object Identifiers или OID в точечной нотации. Эти OID используются для обозначения алгоритмов из кодированных в ASN.1 форматов данных, таких как сертификаты X5.09v3, используемые в SSL/TLS. Например, 1.3.14.3.2.26 представляет собой точечную нотацию для {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) hashAlgorithmIdentifier(26)} и псевдоним для SHA/SHA-1,

 --- Provider SUN, version 1.80 --- 
Algorithm name: "MD2"
Algorithm name: "MD5"
Algorithm name: "SHA"
Algorithm name: "SHA-224"
Algorithm name: "SHA-256"
Algorithm name: "SHA-384"
Algorithm name: "SHA-512"
Alias: "SHA-1" -> "SHA"
Alias: "OID.1.3.14.3.2.26" -> "SHA"
Alias: "1.3.14.3.2.26" -> "SHA"
Alias: "OID.2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "OID.2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "OID.2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "OID.2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "SHA1" -> "SHA"

Выпуск провайдера Bouncy Castle

Выход для Bouncy Castle (не предлагается, для сравнения):

 --- Provider BC, version 1.51 --- 
Algorithm name: "GOST3411"
Algorithm name: "MD2"
Algorithm name: "MD4"
Algorithm name: "MD5"
Algorithm name: "SHA-1"
Algorithm name: "RIPEMD128"
Algorithm name: "RIPEMD160"
Algorithm name: "RIPEMD256"
Algorithm name: "RIPEMD320"
Algorithm name: "SHA-224"
Algorithm name: "SHA-256"
Algorithm name: "SHA-384"
Algorithm name: "SHA-512"
Algorithm name: "SHA-512/224"
Algorithm name: "SHA-512/256"
Algorithm name: "SHA3-224"
Algorithm name: "SHA3-256"
Algorithm name: "SHA3-384"
Algorithm name: "SHA3-512"
Algorithm name: "Skein-256-128"
Algorithm name: "Skein-256-160"
Algorithm name: "Skein-256-224"
Algorithm name: "Skein-256-256"
Algorithm name: "Skein-512-128"
Algorithm name: "Skein-512-160"
Algorithm name: "Skein-512-224"
Algorithm name: "Skein-512-256"
Algorithm name: "Skein-512-384"
Algorithm name: "Skein-512-512"
Algorithm name: "Skein-1024-384"
Algorithm name: "Skein-1024-512"
Algorithm name: "Skein-1024-1024"
Algorithm name: "SM3"
Algorithm name: "TIGER"
Algorithm name: "WHIRLPOOL"
Alias: "SHA256" -> "SHA-256"
Alias: "SHA224" -> "SHA-224"
Alias: "1.3.36.3.2.3" -> "RIPEMD256"
Alias: "1.3.36.3.2.2" -> "RIPEMD128"
Alias: "1.3.36.3.2.1" -> "RIPEMD160"
Alias: "1.2.156.197.1.401" -> "SM3"
Alias: "SHA512" -> "SHA-512"
Alias: "SHA1" -> "SHA-1"
Alias: "GOST" -> "GOST3411"
Alias: "2.16.840.1.101.3.4.2.6" -> "SHA-512/256"
Alias: "2.16.840.1.101.3.4.2.5" -> "SHA-512/224"
Alias: "2.16.840.1.101.3.4.2.4" -> "SHA-224"
Alias: "2.16.840.1.101.3.4.2.3" -> "SHA-512"
Alias: "2.16.840.1.101.3.4.2.2" -> "SHA-384"
Alias: "2.16.840.1.101.3.4.2.1" -> "SHA-256"
Alias: "1.2.643.2.2.9" -> "GOST3411"
Alias: "1.3.14.3.2.26" -> "SHA-1"
Alias: "SHA512/224" -> "SHA-512/224"
Alias: "GOST-3411" -> "GOST3411"
Alias: "SHA512256" -> "SHA-512/256"
Alias: "SHA384" -> "SHA-384"
Alias: "SM3" -> "SM3"
Alias: "SHA" -> "SHA-1"
Alias: "1.2.840.113549.2.5" -> "MD5"
Alias: "1.2.840.113549.2.4" -> "MD4"
Alias: "1.2.840.113549.2.2" -> "MD2"

Ответ 2

В документации говорится:

Эти алгоритмы описаны в разделе MessageDigest стандартной архитектуры алгоритма архитектуры криптографической архитектуры Java

Связанный документ содержит следующую строку сразу после оглавления:

Примечание. Документация Oracle Providers содержит информацию о конкретном поставщике и алгоритме.

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

Ответ 3

Чтобы получить только имена алгоритмов, без псевдонимов или какой-либо дополнительной информации, самое простое:

import java.security.Security;
import java.util.Set;

...

Set<String> algorithms = Security.getAlgorithms("MessageDigest");

since Java 1.4

Ответ 4

В дополнение к Maarten Bodewes ответ: мне нужен такой алгоритм, и я написал метод, собирая отсортированный по списку имен всех доступных алгоритмов и псевдонимов. Он использует API потока java8. Пожалуйста, не стесняйтесь использовать его там, где хотите. Приветствия.

public static List<String> getAvailableAlgorithms()
{
    final String digestClassName = MessageDigest.class.getSimpleName();
    final String aliasPrefix = "Alg.Alias." + digestClassName + ".";

    return Arrays.stream(getProviders())
        .flatMap(prov -> {
            final Set<String> algorithms = new HashSet<>(0);

            prov.getServices().stream()
                .filter(s -> digestClassName.equalsIgnoreCase(s.getType()))
                .map(Service::getAlgorithm)
                .collect(Collectors.toCollection(() -> algorithms));

            prov.keySet().stream()
                .map(Object::toString)
                .filter(k -> k.startsWith(aliasPrefix))
                .map(k -> String.format("\"%s\" -> \"%s\"", k.substring(aliasPrefix.length()), prov.get(k).toString()))
                .collect(Collectors.toCollection(() -> algorithms));

            return algorithms.stream();
        })
        .sorted(String::compareTo)
        .collect(Collectors.toList());
}

Ответ 5

Один лайнер:

Arrays.stream(Security.getProviders())
            .flatMap(provider -> provider.getServices().stream())
            .filter(s -> MessageDigest.class.getSimpleName().equals(s.getType()))
            .map(Provider.Service::getAlgorithm)
            .collect(Collectors.toList());

Ответ 6

Вы можете найти точный список поддерживаемых вашей JVM с помощью следующего кода:

java.lang.System.out.println(java.security.Security.getAlgorithms("MessageDigest"));

Если вы недавно установили JRE/JDK, у вас должен быть доступен JavaScript, поэтому вы можете запустить "jjs" (который должен находиться в том же каталоге, что и java/javac/...) и набрать приведенную выше команду в командной строке. Очевидно, что если вы установили специальных провайдеров (таких как Bouncy Castle) в своей JVM, вам нужно будет настроить их соответствующим образом при запуске "jjs".