1. Overview

In this quick tutorial, we’ll learn about the Cipher class in Java. Then, we’ll see how to list the available cipher algorithms and their providers.

2. The Cipher Class

The Cipher class, which is located in the javax.crypto package is the core of the Java Cryptography Extension (JCE) framework. This framework provides a set of cryptographic ciphers for data encryption, decryption, and hashing.

3. Listing the Cipher Algorithms

We can instantiate a cipher object by calling the Cipher.getInstance() static method with the name of the requested transformation as the argument:

Cipher cipher = Cipher.getInstance("AES");

There are some cases we need to get the list of available cipher algorithms and their providers. For instance, we want to check if a specific algorithm is available based on the libraries present in the classpath.

First, we need to get the list of registered providers using the Security.getProviders() method. Then, calling the getServices() method on the Provider object will return an unmodifiable set of all services supported by this Provider:

for (Provider provider : Security.getProviders()) {
    for (Provider.Service service : provider.getServices()) {
        String algorithm = service.getAlgorithm();
        // ...
    }
}

The list of available algorithms :

SHA3-224
NONEwithDSA
DSA
JavaLoginConfig
DSA
SHA3-384
SHA3-256
SHA1withDSA
...

However, not all of the listed algorithms are supported as a transformation by Cipher.getInstance() static method. For example, instantiating a cipher object with SHA3-224, which is a hashing algorithm, will throw a NoSuchAlgorithmException:

Cipher cipher = Cipher.getInstance("SHA3-224");

Let’s take a look at the runtime exception message:

java.security.NoSuchAlgorithmException: Cannot find any provider supporting SHA3-224

So, we need to filter the list and keep services with the Cipher type. We can use a Java stream to filter and collect the list of the names of the compatible algorithms:

List<String> algorithms = Arrays.stream(Security.getProviders())
  .flatMap(provider -> provider.getServices().stream())
  .filter(service -> "Cipher".equals(service.getType()))
  .map(Provider.Service::getAlgorithm)
  .collect(Collectors.toList());
// ...

The result will be something like:

AES_192/CBC/NoPadding
AES_192/OFB/NoPadding
AES_192/CFB/NoPadding
AESWrap_192
PBEWithHmacSHA224AndAES_256
AES_192/ECB/NoPadding
AES_192/GCM/NoPadding
ChaCha20-Poly1305
PBEWithHmacSHA384AndAES_128
AES_128/ECB/NoPadding
AES_128/OFB/NoPadding
AES_128/CBC/NoPadding
...

4. Conclusion

In this tutorial, we first learned about the Cipher class. Then, we learned how to list the available cipher algorithms.

As usual, all the examples are available over on GitHub.