The Java Cryptography Architecture is split into two different packages, part lies within the JDK, while the other lies within the Java Cryptology Extension. Sun had to split the architecture due to US export laws which prohibits software encryption technology from being released outside of the United States or Canada (certain types of cryptographic software are considered “weapons” by the U.S. government).
Cryptography in Java was first released in JDK 1.1. It included APIs for digital signatures and message digests (hash), but was limited compared to what the platform offers today. The JDK 1.2 added security APIs that relate to cryptography, and also the Java Cryptography Extension, a separate extension with encryption, key exchange, message digest and authentication. The JCE was released separately in accordance with the United States export laws.
Cryptography in the JDK
The JDK 1.2 includes the following service classes:
- Signature — Used to sign and verify digital signatures.
- Message Digest — Used to calculate the message digest (hash) of specified data.
- KeyPairGenerator — Generate a pair of public and private keys suitable for a specific algorithm
- KeyFactory — Converts cryptographic keys of type ‘key’ into key specifications.
- AlgorithmParameterGenerator — Generates parameters for a particular algorithm.
- AlgorithmParameters — Manages the parameters for a particular algorithm
- KeyStore — Used to create and manage a key store.
- CertificateFactory — Defines the functionality of a certificate factory, used to generate certificate and CRL objects from their encodings.
- SecureRandom — Generates pseudo random numbers.
These service classes provide an interface to the functionality of a specific service or Cryptographic Security Provider by defining the APIs that allow access. The Application Interfaces supplied by a service class are implemented in terms of a SPI (Service Provider Interface). For each service class there is an abstract SPI class that defines the SPI methods which a specific cryptography service provider must implement.
The Java Cryptography Extension
The JCE removes users from the implementation of cryptography, and the algorithms involved, making both easy to use. A programmer can specify algorithms, or the JCE architecture will choose the default algorithms. The JCE uses a provider based architecture, based on using Cryptographic Security Providers (CSPs). An application that uses an object that needs a specific CSP service or algorithm will run through the installed providers, and choose the first default provider with an appropriate service. Alternately programmers can choose specific providers for specific services.
The original JCE extension included the following packages:
— Includes classes and interfaces for various cryptographic operations.javax.crypto
— Includes interfaces for Diffie-Hellman keys.javax.crypto.interfaces
— Holds classes and interfaces for key specifications and algorithm parameter specifications.javax.crypto.spec
Recently, the JCE 1.2.1 was released Sun. The primary difference between JCE 1.2 and JCE 1.2.1 is that JCE 1.2.1 is exportable outside the U.S. and Canada due to mechanisms it implements to ensure that only qualified providers can be plugged into the framework. It does this by using added jurisdiction policy files, which are transparent, do not cause any API changes, and differentiate between U.S. and other country specific laws. JCE 1.2.1 also includes more support for key wrapping, key usage and control. Added are functions to retrieve key sizes, which are necessary to enforce the jurisdiction policies, and the
javax.cryptoExemptionMechanism |
javax.crypto.ExeptionMechanismSPI |
Random Numbers
Random numbers are crucial to cryptography. They are used to create cryptographic keys and to encrypt or sign data.
Java has had historic difficulty generating random numbers. Most random number generators are hardware dependent, or require specialized hardware. Java, by principle, is hardware independent, and so uses pseudorandom number generators.
Pseudorandom numbers are numbers that are actually generated by a deterministic procedure, and so are not truly random, but the procedure makes any relationship among the numbers unnoticeable by most applications. Linear congruential method is the default method set for Java’s two built in random number generators:
java.util.random |
java.security.SecureRandom |
Random uses a 48 bit seed. The user can construct a Random object and assign it a seed either on the constructor or by using the setSeed method. If a seed isn’t assigned, Random turns to the system clock.
SecureRandom was added in JDK 1.1 because the simple
java.util.random |
While the
java.util.random |
java.security.SecureRandom |
To use SecureRandom, you create a SecureRandom instance and call its
nextBytes() |
SecureRandom random = new SecureRandom();
byte[] pseudoRandom = new byte [numberofbyteshere];
random.nextBytes(pseudoRandom);SecureRandom can also be set to use a specific provider:
SecureRandom random = SecureRandom.getInstance(“specificalgorythmproviderhere”);
random.setSeed(seed);
Cryptographic Security Providers (CSPs)
Added in JCE 1.1, CSPs were included to provide keyfactories, keystore creation and management, algorithm parameter management, algorithm parameter generation, certificate factories, and random number generators (RNGs). Sun includes a default provider, “SUN”. Provider lists allow programmers to specify the algorithms used for cryptography, or alternately, the provider list has a preference order, and an object searching for a specific provider for an algorithm will simply run down the list until it finds one that is suitable.
This allows providers to be assigned statically or dynamically. The user can install the provider classes by placing a ZIP JAR file containing the classes anywhere on CLASS PATH, or supply the provider JAR file as an installed or bundled extension. The user can add providers dynamically by using addProvider, but only with a program or applet that is considered trusted. The java security properties file can also be edited. Providers are stored in the following format:
security.provider.n=masterClassName
The variable n is equal to the provider preference order. When searching for a service with no specified provider, the search order is determined by this value, starting with
security.provider.1 |
Sun lists several compatible cryptographic service providers:
- RSA Data Security Inc.
- eSec Limited (formally Australian Business Access )
- Forge Research
- DSTC
- IAIK
- Entrust Technologies
- Cryptix
It is also relatively easy to program your own default provider, which will be discussed in part two of this series.
References and Resources
- Inside Java 2 Platform Security, Li Gong, Addison Wesley, 1999
- Introduction to Algorithms A Creative Approach, Udi Manber, Addison Wesley Publishing Company, 1989
- Java Cryptology, Jonathon Knudsen, O’reily and Associates, 1998
- Java Security Handbook, Jamie Jaworski and Paul Perrone, SAMS Publishing, 2000
About the Author
Thomas Gutschmidt is a freelance writer, in Bellevue, Wash., who also works for Widevine Technologies.