Cryptography in Java

The cryptographic functionality in Java is provided mainly by two libraries, Java Cryptography Architecture (JCA) and Java Cryptography Extension (JCE). The first one, JCA, is tightly integrated with the core Java API, and delivers the most basic cryptographic features. The latter one, JCE, provides various advanced cryptographic operations.

In the past, both JCA and JCE libraries used to be treated differently by US export policies. Over time however the regulations were relaxed, and at present they both are delivered as part of Java SE and the division is no longer important (one should keep in mind that it does not mean that the law won't change in the future).

The API functions and classes defined in JCA and JCE allow cryptographic operations to be performed in Java applications. In addition to operations, the classes describe various objects and security concepts. All classes belonging to JCA and JCE are called engines.

All JCA engines are located in the java.security package, whereas the JCE classes are located in the javax.crypto package.

Among others, JCA delivers engines for random number generation (SecureRandom), key generation and management (KeyPairGenerator, KeyStore), message authentication (MessageDigest, Signature), and for certificate management (CertificateFactory, CertPathBuilder, CertStore).

JCA contains engines that allow actual encryption and decryption (Cipher), secret key generation and agreement (KeyGenerator, SecretKeyFactory, KeyAgreement), and message authentication operations (Mac).

Providers

Whilst JCA and JCE define all cryptographic operations and objects, the actual implementations of functionalities are located in separate classes, called providers. The providers implement the API defined in JCA and JCE, and they are responsible for providing the actual cryptographic algorithms.

Thanks to that, the whole cryptographic architecture is relatively flexible. It separates the interfaces and generic classes from their implementations. For most of the time, after the initialization, the programmers need to deal only with abstract terms, like 'cipher' or 'secret key'.

In order to be used in Java applications, all providers must be signed by using a certificate from Oracle. A detailed instruction can be found in the JDK documentation.

The providers can be installed by configuring the Java Runtime: installing the JAR containing the provider, and then enabling it by adding its name to the java.security file. Alternatively, the providers may be installed during execution (by calling Security.addProvider(..) function) by the application itself.

Each functionality, for example the AES cipher algorithm, may be defined by several providers. The application, when calling the JCA and JCE API functions, can specify which provider should be used. Alternatively, the Java engine will choose an available provider based on the preference order specified in the java.security file.

Popular Providers

A default set of SUN providers (nowadays owned by Oracle) is installed together with the main Java cryptographic functionality. There are many different kinds of SUN providers (SUN, SunJCE, SunPKCS11, and so on), and they are used by both JCA and JCE libraries. They define most (if not all) cryptographic functionalities and can be used strait away in Java applications.

An example of different providers is the collection of classes called Bouncy Castle. It was developed by an Australian charitable organization, so the US law restrictions do not apply to it. Bouncy Castle provides a large number of classes implementing various cryptographic operations. The project full description may be found on the website: www.bouncycastle.org.

Another set of providers were created by Cryptix organization, however the project has not been actively developed since 2005. Cryptix website is located at: www.cryptix.org.

Policy Files

By default, Java cryptographic functionalities have some limitations related to the size of various types of secret keys. The restrictions are related to the US law and they are supposed to prevent the application from using too strong ciphers.

One can overcome the limitations by downloading and applying the unlimited strength policy files. They can usually be acquired from the original Java download web page. The download link is usually located somewhere at the bottom of the page. After getting the packed archive, the user should follow the instructions that can be found in the README file.