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?
Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value. A MessageDigest object starts out initialized. The data is processed through it using the update methods. At any point reset can be called to reset the digest.
Comments. MessageDigest supports one-way hash algorithms. You can't decrypt them. Usually people will take a string password, hash it using SHA or MD5 and then when the user enters the password later, they hash that using the same algorithm and compare it to the first one.
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.
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);
}
}
}
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"
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"
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
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.
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With