8.3. The Security ClassThe 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). Like the System and Math classes, then, 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 feat can be accomplished programmatically via these methods of the Security class:
The notion that these classes are kept in an indexed array is important; when the Security class is asked to provide a particular algorithm for an operation, the array is searched sequentially for a provider that can provide the requested algorithm for the requested operation. As an example, let's use a modification of the XYZProvider class that we outlined earlier. This class comes with a set of classes to perform generation of key pairs, and it can generate key pairs according to two algorithms: DSA and XYZ. The XYZProvider class, according to an entry added to the java.security file, has been added at position 2. Additionally, let's say that our Java program has installed an additional provider class at position 3 called the FooProvider that can generate key pairs and digital signatures according to a single algorithm known as Foo. This leaves us with the set of provider classes listed in Table 8-3. Table 8-3. Sample Security Providers
Now when our Java program needs to generate a key pair, the security provider is consulted as to which classes will implement the key pair generation we want. If we need to generate a DSA key, the security provider returns to us a class associated with the Sun provider class, since the Sun provider, at position 1, is the first class that says that it can perform DSA key generation. If we had reversed the order of indices in the java.security file so that the Sun provider was at position 2 and the XYZ provider was at position 1, a class associated with the XYZ provider would have been returned instead. Similarly, when we request a Foo key pair, a class associated with the Foo provider is returned to us, regardless of what index it occurs at, since that is the only provider class that knows how to perform Foo key generation. Remember that this is a two-step process. The security class receives a string (like KeyPairGenerator.DSA) and locates a class that provides that service (such as sun.security.provider.Sun). The Sun class, as a provider class, does not actually know how to generate keys (or do anything else)--it only knows what classes in the Sun security package know how to generate keys. Then the security class must ask the provider itself for the name of the class that actually implements the desired operation. That process is handled by an internal method of the Security class--we'll use that method implicitly over the next few chapters when we retrieve objects that implement a particular engine and algorithm. Before we do that, though, we'll finish looking at the interface of 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.
Here's a simple example, then, of how to see a list of all the security providers in a particular virtual machine: Class Definitionpublic 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); } } } If we run this program with the 1.2 Sun security provider, we get this output: Class DefinitionSUN version 1.2 Alg.Alias.MessageDigest.SHA Alg.Alias.Signature.SHAwithDSA Alg.Alias.Signature.1.3.14.3.2.13 Alg.Alias.Signature.OID.1.2.840.10040.4.3 Alg.Alias.Signature.SHA-1/DSA Alg.Alias.Signature.DSS Alg.Alias.Signature.SHA1withDSA Alg.Alias.Signature.OID.1.3.14.3.2.13 AlgorithmParameters.DSA KeyFactory.DSA Alg.Alias.Signature.1.2.840.10040.4.3 Alg.Alias.MessageDigest.SHA1 AlgorithmParameterGenerator.DSA Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1 MessageDigest.MD5 Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1 MessageDigest.SHA-1 Alg.Alias.KeyPairGenerator.OID.1.3.14.3.2.12 Signature.DSA Alg.Alias.KeyPairGenerator.1.3.14.3.2.12 Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1 Alg.Alias.Signature.1.3.14.3.2.27 Alg.Alias.Signature.SHA/DSA KeyPairGenerator.DSA Alg.Alias.Signature.SHA1/DSA Alg.Alias.Signature.OID.1.3.14.3.2.27 Alg.Alias.AlgorithmParameters.1.3.14.3.2.12 KeyStore.JKS CertificateFactory.X509 Alg.Alias.CertificateFactory.X.509 SecureRandom.SHA1PRNG Two things are readily apparent from this example. First, the strings that contain only an engine name and an algorithm implement the expected operations that we listed in Table 8-1. Second, as we mentioned in the section on the Provider class, security providers often leverage the fact that the Provider class is a subclass of the Properties class to provide properties that may make sense only to other classes that are part of the provider package. Hence, the signature algorithm 1.3.14.3.2.13 may make sense to one of the classes in the Sun security provider, but it is not a string that will necessarily make sense to other developers. In fact, those aliases--including the ones that are prefaced by OID--do have meanings within the cryptography standards world, but for our purposes we'll stick with the standard algorithm names that we listed earlier. 8.3.1. The Security Class and the Security ManagerAll the public methods of the Security class call the checkSecurityAccess() method of the security manager. This gives the security manager the opportunity to intervene before an untrusted class affects the security policy of the virtual machine. Recall that the checkSecurityAccess() method accepts a single string parameter. In the case of the methods in the Security class, the call that is made looks like this: Class Definitionpublic static Provider getProvider(String name) { SecurityManager sec = System.getSecurityManager(); if (sec != null) sec.checkSecurityAccess("java"); ... continue to find the provider ... } The string parameter that is sent to the checkSecurityAccess() method has changed between releases of Java; the various methods and the strings they pass to the security manager are listed in Table 8-4. Table 8-4. Security Checks of the Security Class
In typical usage in 1.1, the security manager ignores this string altogether and simply allows all trusted classes to call these methods and prevents all untrusted classes from calling these methods. In 1.2, the security manager constructs a security permission for the given name and calls the access controller to see if the given permission has been granted. Copyright © 2001 O'Reilly & Associates. All rights reserved. |
|