javax.crypto - Cipher objects - How does the Provider Service work?

229 views Asked by At

I am trying to find the implementations of the source code.
For example, if I initialize the Cipher-object like this:

Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

how can I find the actual implementaion of the AES-Algorithm that is used and of the CTR-mode?

If I am looking up the source code of Cipher.java than you can see that the getInstance()-method uses some service-providers. I am guessing that the line:

List<Service> services = GetInstance.getServices(cipherServices);

is responsible for matching the "AES/CTR/NoPadding" to the CipherSpi-object that is created.

But now I am stuck and I do not know what is going on. How is this working? Where can I find the source code to AES and CTR? Is it matched to the classes in this .../sun/crypto/provider folder? How does this matching work? Where can I see what is matched to what input? What I am also trying to figure out is if the CTR-Mode uses some sort of parallelism.

2

There are 2 answers

3
Progman On BEST ANSWER

The Cipher object has a method getProvider() to return the Provider instance, that was used to create the Cipher object. This class has several methods to get information about the provider itself like the name. You can use this information to "reverse engineer" which class or package is implementing the cipher. See the following example:

Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
System.out.println(cipher);
System.out.println(cipher.getClass());
Provider provider = cipher.getProvider();
System.out.println(provider);
System.out.println(provider.getName());
System.out.println(provider.getInfo());
System.out.println(provider.getClass());

This can generate an output like this (with openjdk version "1.8.0_362"):

javax.crypto.Cipher@7440e464
class javax.crypto.Cipher
SunJCE version 1.8
SunJCE
SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
class com.sun.crypto.provider.SunJCE

You can check the JDK or any installed provider JAR (like BouncyCastle) for the implementation class. For OpenJDK, the implementation of that class is at https://github.com/openjdk/jdk/blob/b3cc0c84316dd59f406a6fa23fcaf3d029910843/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java. From there you can check other related classes like AESCipher or AESCrypt.

2
Asthor On

There is no direct answer to your question as this varies based on among other which JDK you are currently using.

Quoting directly from the Java Cryptography Architecture documentation for Java 17 it sates

java.security.Provider is the base class for all security providers. Each CSP [Cryptography Security Provider] contains an instance of this class which contains the provider's name and lists all of the security services/algorithms it implements. When an instance of a particular algorithm is needed, the JCA framework consults the provider's database, and if a suitable match is found, the instance is created.

Providers contain a package (or a set of packages) that supply concrete implementations for the advertised cryptographic algorithms. Each JDK installation has one or more providers installed and configured by default. Additional providers may be added statically or dynamically. Clients may configure their runtime environment to specify the provider preference order. The preference order is the order in which providers are searched for requested services when no specific provider is requested.

So depending on your setup, it can be any of the provided algorithms for AES/CTR/NoPadding with your JDK.

You can control which provider you use by supplying which provider you'd prefer through

Cipher.getInstance("AES/CTR/NoPadding", "Provider");