25

I've searched high and low for this, but I can't seem to get a straight answer.

In Java, the available MessageDigests are determined by which security providers you have configured/installed. But assuming just a normal JDK8 install (1.8.0_11 in my case), what's the list of hash algorithms that are available? From examples in the docs, it's obvious MD5, SHA1 and SHA-256 are available, but I can't seem to get a complete, authoritative list.

Does this list exist, or how do I go about finding out for my particular install?

mjuarez
  • 16,372
  • 11
  • 56
  • 73
  • possible duplicate of [How can I list the available Cipher algorithms?](http://stackoverflow.com/questions/9333504/how-can-i-list-the-available-cipher-algorithms) – DavidPostill Jul 27 '14 at 09:38
  • @DavidPostill Don't agree about the dupe, those kind of dupes won't show up in search results. We *could* create a generic Q/A for any kind of `Service` in the JDK, but without it, asking for each and every type of algorithm should be OK. – Maarten Bodewes Jul 27 '14 at 16:34
  • @owlstead I knew about the other answer as I used some code from it in something I was playing around with some time ago. So I could search for "Cipher" to find it. – DavidPostill Jul 27 '14 at 16:49
  • 1
    @DavidPostill Well, that's great, but would you assume that everybody else would be able to do the same thing? I'm looking for `SecureRandom` implementation, let's replace it with `Cipher` so we can find a solution? Not everybody will think of that solution. And why not replace it with `Signature`, or `Mac`? – Maarten Bodewes Jul 27 '14 at 17:05
  • @owlstead No I would not make that assumption. That's exactly why I flagged as a possible duplicate ... it enables someone to at least find the other answer ... do you have a better suggestion as to how I should handle a similar situation next time if flagging as duplicate is not appropriate? – DavidPostill Jul 27 '14 at 17:14

6 Answers6

37

In addition to JB's answer, I would like to propose a solution that queries the runtime for available algorithms. This method is of course easily converted to one for Cipher, SecureRandom, Mac, KeyAgreement, KeyFactory or any other type of algorithm.

Program

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 provider output

This code will generate the following output for Java 1.8. Note that because of some old mistake by the API providers, the provider version is only present as a double. It is not possible to distinguish between version 1.80 or version 1.8.0 because of this.

The aliases are below the actual implementations. Some of these aliases are Object Identifiers or OID's in dot notation. These OID's are used to indicate algorithms from within ASN.1 encoded data formats such as X5.09v3 certificates as used within SSL/TLS. For instance, 1.3.14.3.2.26 is the dot notation for {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) hashAlgorithmIdentifier(26)} and the alias for 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 provider output

Output for Bouncy Castle (not asked for, included for comparison):

 --- 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"
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
14

To get just the algorithm names, without aliases or any additional information, the simplest is:

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

...

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

Note that you should configure any non-standard providers before calling this function, e.g. by using Security.addProvider(Provider provider).

since Java 1.4

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
user85421
  • 28,957
  • 10
  • 64
  • 87
3

The documentation says:

These algorithms are described in the MessageDigest section of the Java Cryptography Architecture Standard Algorithm Name Documentation

The linked document contains the following line, right after the table of contents:

Note: The Oracle Providers Documentation contains specific provider and algorithm information.

And the linked document contains the complete list of MessageDigest algorithms provided by each provider.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks @JB Nizet, I did get to the JCA doc, but then I guess didn't pay enough attention. Thanks! – mjuarez Jul 27 '14 at 09:48
1

In addition to Maarten Bodewes's answer: I needed such algorithm and I wrote a method, collecting a sorted by name list of all available algorithms and aliases. It uses java8's stream API. Please, feel free to use it wherever you want. Cheers.

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());
}
Netherwire
  • 2,669
  • 3
  • 31
  • 54
1

One liner:

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

You can find the exact list supported by your JVM with the following code:

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

If you have a recent JRE/JDK, you should have JavaScript available thus you can launch "jjs" (which should be in the same directory as java/javac/...) and type the above command at the prompt. Obviously, if you have installed special providers (like Bouncy Castle) in your JVM, you will need to configure them accordingly when launching "jjs".

  • This is basically a [direct copy of an answer provided earlier in the same year](https://stackoverflow.com/a/57473282/589259). I've added the fact that it would be a good idea to add additional providers there as it only expands that answer. – Maarten Bodewes Sep 20 '22 at 11:00