Examining Keystore Data The keytool

The KeyStore class is an engine class; there is a corresponding KeyStoreSpi class that you can use to write your own keystore more about that a little later. As weve seen, the Sun−supplied algorithms for this engine are JKS, JCEKS, and PKCS12. Instances of the KeyStore class are predictably obtained via this method: public static final KeyStore getInstanceString type public static final KeyStore getInstanceString type, String provider Return an instance of the KeyStore class that implements the given algorithm, supplied by the given provider, if applicable. If you do not want to hardwire the name of the keystore algorithm into your application, you may use this method to return the string that should be passed to the getInstance method: public static final String getDefaultType Return the default keystore algorithm for the environment. This value is obtained by looking for a property called keystore.type in the java.security file; Suns version of Java sets the default value of this string to JKS. When the keystore object is created, it is initially empty. Although the getInstance method has constructed the object, it is not expected that the objects constructor will read in a keystore from any particular location. The interaction between the keystore object and the keytool database comes via these two methods: public final void loadInputStream is, char[] password Initialize the keystore from the data provided over the given input stream. The integrity of the keystore is protected by using a message digest: when the keystore is stored, a message digest that represents the data in the keystore is also stored. Before the digest is created, the password is added to the digest data; this means that the digest cannot be recreated from a keystore without knowledge of the password. This allows you to detect whether the keystore has been tampered with. The password for this method can be null , in which case the keystore is loaded and not verified. Its somewhat misleading to call this parameter a password, although thats what the javadoc calls it, and thats the term used by keytool . If you pass null for the password, youll always be able to read the keystore. Remember that a different password is used to decrypt the private keys in the keystore, so this isnt a security hole: if you dont have the password, you will be able to read only public certificates. If you use an incorrect password, an IO exception is thrown. You cannot require a password for the load method to succeed since the Sun implementation of the Policy class calls this method without a password when it constructs the information needed for the access controller. You may, of course, provide your own implementation of the Policy class that requires a password. If the class required to support the underlying message digest is not available, a NoSuchAlgorithmException is thrown. An error in reading the data results in an IOException , and generic format errors in the data result in a CertificateException . public final void storeOutputStream os, char[] password Store the keystore to the given output stream. The password is typically included in a digest calculation of the keystore; this digest is then written to the output stream as well but again, your own implementation of this class could use the password differently. The format of the data is completely implementation dependent. This method may throw an IOException if the output stream cannot be read, a NoSuchAlgorithmException if the class used to create the digest cannot be found, or a CertificateException if the keystore object contains a certificate that cannot be parsed. There is no default file that holds the keystore. Within the core Java API, the only class that opens the keystore is the PolicyFile class, and that opens the keystore that is listed in the java.policy files. The tools that use the keystore the jarsigner and keytool tools allow you to use a command−line argument to specify the file that contains the keystore; they default to the file .keystore in the users home directory. This is the convention your own programs will need to use. If your application needs to open the keystore for example, to obtain a private key to sign an object, it should provide either a command−line argument or a property to specify the name of the file to open, and they should provide a reasonable default. Following convention, well use the .keystore file in the users home directory in our examples. As weve seen, a keystore is arranged in terms of alias names. Aliases are arbitrarily assigned to an entry; while the name embedded in the certificate for a particular entry may be a long, complicated, distinguished name, the alias for that entry can provide a shorter, easier−to−remember name. There are a number of simple methods in the KeyStore class that deal with these alias names: public final Date getCreationDateString alias Return the date on which the entry referenced by the given alias was created. public final void deleteEntryString alias Delete the entry referenced by the given alias from the keystore. public final Enumeration aliases Return an enumeration of all the aliases in the keystore. public final boolean containsAliasString alias Indicate whether the keystore contains an entry referenced by the given alias. public final int size Return the number of entriesaliases in the keystore. public final boolean isKeyEntryString alias public final boolean isCertificateEntryString alias Indicate whether the given alias represents a key entry or a certificate entry. public final Key getKeyString alias, char[] password Return the private or secret key for the entry associated with the given alias. For a certificate entry, this method returns null . An UnrecoverableKeyException is thrown if the key cannot be