Lecture 08
Lecture 08
Security Providers
Security Providers
• Java includes The cryptographic engines in Java that provide for digital
signatures, message digests, and the like are provided as a set of APIs
in the Java security package.
• APIs allow for multiple interoperable implementations of algorithms
and other security services. Services are implemented in providers.
• Java includes a number of providers that implement a core set of
security services. It also allows for additional custom providers to be
installed.
• java.security.Provider class encapsulates the notion of a security
provider in the Java platform
Java Cryptography Architecture (JCA)
• JCA is a major piece of the platform, and contains a "provider" architecture and a set of APIs for
digital signatures, message digests (hashes), certificates and certificate validation, encryption, key
generation etc.
• These APIs allow developers to easily integrate security into their application code. The architecture
was designed around the following principles:
• Implementation independence: Applications do not need to implement security algorithms. Rather,
they can request security services from the Java platform. Security services are implemented in
providers which are plugged into the Java platform via a standard interface. An application may rely
on multiple independent providers for security functionality.
• Implementation interoperability: Providers are interoperable across applications. Specifically, an
application is not bound to a specific provider, and a provider is not bound to a specific application.
• Algorithm extensibility: The Java platform includes a number of built-in providers that implement a
basic set of security services that are widely used today. However, some applications may rely on
emerging standards not yet implemented, or on proprietary services. The Java platform supports the
installation of custom providers that implement such services.
Components of the Architecture
• The architecture surrounding all of this has these components:
• Engine classes
• These classes come with the Java virtual machine as part of the core API.
• Algorithm classes
• At the basic level, there is a set of classes that implement particular algorithms for particular engines. A
default set of these classes is provided by the supplier of the Java platform; other third−party organizations can
supply additional sets of algorithm classes. These classes may implement one or more algorithms for one or
more engines; it is not necessary for a set of classes from a particular vendor to implement all possible
algorithms or all possible engines. A single algorithm class provides a particular algorithm for a particular
engine.
• The Provider class
• Each set of algorithm classes from a particular vendor is managed by an instance of the class Provider. A
provider knows how to map particular algorithms to the actual class that implements the operation.
• The Security class
• The Security class maintains a list of the provider classes and consults each in turn to see which operations it
supports.
Choosing a Security Provider
• When the Java virtual machine begins execution, it is responsible for consulting the user's properties in order to
determine which security providers should be in place.
• These properties must be located in the file $JREHOME/lib/security/java.security. In any given Java Virtual
Machine (JVM), providers are installed in a given preference order:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
• These lines tell us that there are at least two provider classes that should be consulted; the first class to be
consulted is an instance of the sun.security.provider.Sun class and the second class is an instance of the
sun.security.rsa.SunRsaSign class.
• Each provider given in this file must be numbered, starting with 1. If you want to use additional providers, you can
edit this file and add those providers at the next numbers.
• When you obtain JCE, you are told that its provider's class name is com.sun.crypto.provider.SunJCE; the classname
of the provider in JSSE is com.sun.net.ssl.internal.ssl.Provider. Hence, to use these providers you add these lines to
the java.security file.
security.provider.3=com.sun.crypto.provider.SunJCE
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
The Provider Class
• The first class we'll examine in depth is the Provider class (java.security.Provider).
• public abstract class Provider extends Properties
• This class forms the basis of the security provider architecture. There is normally a standard
subclass that implements a default security feature set; other classes can be installed to
implement other security algorithms.
• In the core Java API, the Provider class is abstract and there are no classes in the core Java
API that extend the Provider class.
• The default provider class that comes with Sun's implementation of Java is the class Sun in
the sun.security.provider package.
• This class does contain a number of useful miscellaneous methods; these methods are
generally informational and would be used accordingly:
• public String getName( )
• Return the name of the provider.
Using the Provider Class
• public double getVersion( )
• Return the version number of the provider.
• public String getInfo( )
• Return the info string of the provider.
• public String toString( )
• Return the string specifying the provider; this is typically the provider's name concatenated with the
provider's version number.
• The Provider class overrides three methods of the Properties class :
• public synchronized void clear( )
• If permission is granted, clear out all entries from the provider.
• public synchronized Object put(Object key, Object value)
• If permission is granted, add the given property, keyed off the given key.
• public synchronized Object remove(Object key)
• If permission is granted, remove the object associated with the given key.
The Security Class
• The Security class (java.security.Security) is responsible for managing the set of provider classes
that a Java program can use and forms the last link in the architecture of the security provider.
• This class is final, and all its methods are static (except for its constructor, which is private). The
Security class can never be created or subclassed; it exists simply to provide a placeholder for
methods that deal with the java.security package.
• Earlier, we explained how to add entries to the java.security file to add new providers to the
security architecture. The same can be accomplished programmatically via these methods of the
Security class:
• public static int addProvider(Provider provider)
• Add a new provider into the list of providers. The provider is added to the end of the internal array of
providers.
• public static int insertProviderAt(Provider provider, int position)
• Add a new provider into the internal array of providers. The provider is added at the specified position;
other providers have their index changed if necessary to make room for this provider. Position counting
begins at 1.
The Security Class
• There are a number of other methods in the Security class that provide basic
information about the configuration of the security provider:
• public static void removeProvider(String name)
• Remove the named provider from the list of provider classes. The remaining providers
move up in the array of providers if necessary. If the named provider is not in the list,
this method silently returns (i.e., no exception is thrown).
• public static Provider[] getProviders( )
• Return a copy of the array of providers on which the Security class operates. Note that
this is a copy of the array; reordering its elements has no effect on the Security class.
• public static Provider getProvider(String name)
• Return the provider with the given name. If the named provider is not in the list held by
the Security class, this method returns null.
The Security Class
• public static String getProperty(String key)
• Get the property of the Security class with the associated key. The properties held in the Security class
are the properties that were read from the java.security file. In typical usage, one of the properties is
security.provider.1 (as well as any other providers listed in the java.security file). Note, however, that
properties of this sort may not reflect the actual order of the provider classes: when the addProvider( ),
insertProviderAt( ), and removeProvider( ) methods are called, the order of the providers changes. These
changes are not reflected in the internal property list.
• The java.security file has a number of other properties within it; these other properties may also be
retrieved via this method.
• public static void setProperty(String property, String value)
• Set the given property to the given value.
• public static String getAlgorithmProperty(String algName, String propName)
• Search all the providers for a property in the form Alg.propName.algName and return the first match it
finds. For example, if a provider had set the Alg.NativeImplementation.XYZ property to the string "false,"
a call to getAlgorithmName("XYZ", "NativeImplementation") returns the string "false" (which is why
earlier we used a string value in the provider class).
The Security Class
• Here's a simple example of how to see a list of all the security providers in a particular virtual
machine:
import java.security.*;
import java.util.*;
public class ExamineSecurity {
public static void main(String args[]) {
try {
Provider p[] = Security.getProviders( );
for (int i = 0; i < p.length; i++) {
System.out.println(p[i]);
for (Enumeration e = p[i].keys(); e.hasMoreElements( );)
System.out.println("\t" + e.nextElement( ));
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
The Architecture of Engine Classes
• Most programmers are only interested in using the engine classes to
perform their desired operation; each engine class has a public interface
that defines the operations the engine can perform.
• The engine classes are designed so that users can employ third−party
security providers (using the architecture we've just examined).
• For programmers who are interested in writing such providers, the
engine classes have an additional interface called the security provider
interface (SPI).
• The SPI is a set of abstract methods that a particular engine must
implement in order to fulfill its contract of providing a particular
operation.
The Architecture of Engine Classes
• If you want to implement a security provider, you extend the SPI of each engine that
you want to provide. This allows a developer to request a particular engine and
receive the correct class according to the following algorithm:
1. The programmer requests an instance of a particular engine that implements a particular
algorithm. Engine classes never have public constructors; instead, every engine has a
getInstance( ) method that takes the name of the desired algorithm as an argument and
returns an instance of the appropriate class.
2. The Security class is asked to consult its list of providers and provide the appropriate
instance. For example, when the getInstance( ) method of the MessageDigest class is called,
the Security class may determine that the appropriate provider class is called
com.xyz.XYZMessageDigest.
3. If the retrieved class does not extend the appropriate SPI (e.g.,
java.security.MessageDigestSpi in this case), a NoSuchAlgorithmException is generated.
4. An instance of the retrieved class is created and returned to the getInstance( ) method
(which in turn returns it to the developer).
References
• Java Security by Scott Oaks, Second Edition, O’Reilly Media, Inc.
• Oracle JDK 9 Documentation, Java Platform, Standard Edition Security
Developer’s Guide (https://
docs.oracle.com/javase/9/security/toc.htm )