RIM Crypto API: Using the KeyStore

The following tutorial provides information on using the keyStore.

  1. Adding a new key to the key store
  2. Retrieving a key from the key store
  3. Removing an existing key from the key store
  4. Adding a certificate to the key store
  5. Verifying that a certificate exists in the key store
  6. Removing an existing certificate from the key store

Adding a new key to the key store

To add new keys to a particular key store first create an instance of that key store. In the following lines, a new keyStore is created with the label "My Keystore" and the keyPair is created to add to the keyStore. The associated data, which allows you to retrieve an element from the keystore using specific information, is then created.


    RIMKeyStore keyStore = new RIMKeyStore("My Keystore");
    DSAKeyPair keyPair = new DSAKeyPair( new DSACryptoSystem() );
    AssociatedData associatedData = new AssociatedData( AssociatedData.EMAIL, "myemail@mycompany.com".getBytes() );

Once the KeyStore and keyPair are created, the set function of the keyStore method is called. The set method adds a KeyStoreData class containing the information that will be associated with the array of aliases contained inside this class. The set method takes a number of parameters. The associatedData object allows the user to retrieve the key from the keyStore by specifying this data. A descriptive label is then specified which will be displayed to the user in order to identify a key, followed by the private key encoding. The next value, in this case null, specifies the formatting method. By specifying null, the default format, PKCS8 is used.

Next, the security level of the key is specified. In this case, the default keyStore value is specified by using the KeyStore.DEFAULT property. The default security level can be set in the KeyStoreOptions and can be modified at any time. All of the other levels are static which means they are only set once and can never be changed. High security level means that the user will be prompted for a passphrase each time the private key is accessed. Low security level means that the user will not be prompted or notified at all when the private key is accessed.

Next, the public key encoding and public key encoding type are specified. Again, null is specified meaning that the default encoding (X509) will be used to encode the key. Finally, the KeyUsage class is specified. The KeyUsage class defines what the key will be used for. The key store does not prevent people from using these keys with an improper usage but it does provide the mechanism for finding out what the key usage is. The last parameter is the ticket and since we do not have one we supply null.


    try {
        keyStore.set( new AssociatedData[] {associatedData}, "Crypto Signing Key", keyPair.getDSAPrivateKey(), null,
                  KeyStore.DEFAULT, keyPair.getDSAPublicKey(), null, KeyUsage.EMAIL_PROTECTION | KeyUsage.KEY_AGREEMENT,
                  null );
Above, the set statement is called within a try...catch block in order to capture any exceptions that might be thrown. The NoSuchAlgorithmException is thrown if the specified private or public key encoding algorithm does not exist. Since null was passed in above, this exception will not be thrown. The KeyStorePasswordException is thrown when the user clicks cancel instead of entering a password. If this occurs the set operation will obviously fail and the class should exit. This is accomplished using the return statement within the body of the catch clause. The InvalidKeyEncodingException is thrown when an error occurs while encoding the key. The InvalidKeyEncodingException is thrown when the key is improperly formatted and lastly, the CryptoTokenException is thrown when an error occurs with the crypto token.

       } catch( NoSuchAlgorithmException e ) {
            // This occurs when an encoding algorithm is passed in for the private and or
            // public key that does not exist in the system.  This will not occur
            // if you pass in null.
        } catch( KeyStoreCancelException e ) {
            // Thrown when the user cancels the operation to enter their
            // passphrase.  The key was not set.
            return;
        } catch( InvalidKeyEncodingException e ) {
            // Occurs when the encoder is encoding your key and the key
            // you passed in might be invalid in the encoder.
        } catch( CryptoTokenException e ) {
            // Occurs when the encryption of the private key fails
            // due to the software or hardware crypto token.
        } catch( InvalidKeyException e ) {
            // Occurs when there are problems encoding the key.
        } catch( CryptoUnsupportedOperationException e ) {
            // Occurs if the operation being performed is not supported
            // by the current crypto token.
        }


The keyPair (and AssociatedData) has now been added to the keyStore. The keyPair can now be accessed and retrieved from the keyStore by authorized users.

Retrieving a key from the key store

This example builds on the previous sample. Assuming the keyPair exists in the keyStore, how can we retrieve it? The first step in retrieving an element from the keyStore is to create an index and add it to the keyStore. Indexes need to be added to a given keyStore only once. If a user tries to add a second index to a keyStore, the system will prevent it by checking if an index already exists. Below, the index is created using an AssociatedDataKeyStoreIndex. Since we used an AssociatedData object associated with the email address ("myemail@mycompany.com"), the new index is of type AssociatedDataKeyStoreIndex.

        // First we want to build up an index so that we can search for our key.
        AssociatedDataKeyStoreIndex index = new AssociatedDataKeyStoreIndex( AssociatedData.EMAIL );

Next, the index is added to the keyStore using the addIndex method.

        // Add that index to the key store.
        keyStore.addIndex( index );

Next, the get method is used to retrieve the key from the KeyStore. Remember that the key was inserted into the keyStore along with the AssociatedData object. The get method is called using the Index (index.getID) and the bytes associated with the AssociatedData object ("myemail@mycompany.com".getBytes). Because there can be more than one data object in the keyStore, the method returns an enumeration of all keyStoreData objects with matching criteria.


        // Note: index.getID() equals AssociatedData.EMAIL
        Enumeration enum = keyStore.get( index.getID(), "myemail@mycompany.com".getBytes() );

        // Loop through until we find our key.
        KeyStoreData data = null;
        PrivateKey privateKey = null;
        while( enum.hasMoreElements() ) {
            data = (KeyStoreData)enum.nextElement();
            if( "Crypto Signing Key".equals( data.getLabel() ) ) {

Next a while loop is used to loop through the enumeration, matching keys based on the label associated with the key. In the example, the label "Crypto Signing Key" was given to the key.

Since it is entirely possible for two keys to have the same associatedData information and the same label, you may need to prompt the user to determine which key should be retrieved. In this case, since there is only one key in the keyStore, it is a definite match.

To retrieve the private key, use the getPrivateKey method. The method accepts the parameter null, since there is no ticket. Again, this statement occurs within the body of a try...catch statement.


                try {
                    privateKey = data.getPrivateKey( null );
                } catch( NoSuchAlgorithmException e ) {
                } catch( KeyStoreCancelException e ) {
                } catch( InvalidKeyEncodingException e ) {
                } catch( CryptoTokenException e ) {
                } catch( CryptoUnsupportedOperationException e ) {
                } catch( KeyStoreDecodeException e ) {
                }
            }
        }

Removing an existing key from the key store

The following example, building from the previous samples, shows how a key is removed from the key store.

The removeKey method is called, using the keyStoreData object containing the key, to remove the element from the keyStore. The KeyStoreData object was obtained in the previous example.


		try {
             ticket = keyStore.getTicket();
             keyStore.removeKey( data, ticket );
        }
        catch( KeyStoreCancelException e ) {
        }

Note also, that the above example uses a keyStoreTicket. The getTicket method will prompt the user for a passphrase and will return a keyStoreTicket if the operation is successful.

Adding a certificate to the key store

For more information on how to create a certificate, please refer to certificate sample code

        ...
        byte[] certData = { /*[DATA HERE] certificate data as a byte array */ };
        try {
             //assuming that we have a WTLS certificate we create a WTLS certificate
             WTLSCertificate cert = WTLSCertificate( certData );
             //please refer to RIMKeyStore for an overview of the desired
             //parameters in substitution for null
             keyStore.set(null, "my certificate", cert, new CertificateStatus(), null);
             ...
        } catch ( CertificateParsingException e) {
        } catch ( NoSuchAlgorithmException e ) {
        } catch ( InvalidKeyEncodingException e) {
        } catch ( InvalidKeyException e) {
        } catch ( CryptoTokenException e) {
        } catch ( CryptoUnsupportedOperationException e) {
        } catch ( KeyStorePasswordException e) {
        }

Verifying that a certificate exists in the key store

This example demonstrates how to verify that a given certificate currently exists in the keyStore. The isMember method is used to test against the existing certificates in the key store.

       //check if we have inserted the WTLS cert into the key store
       WTLSCertificate myNewCert = WTLSCertificate( certData );
       if ( keyStore.isMember(myNewCert) ) {
            System.out.println("Certificate provided is in the key store");
       }
       else {
            System.out.println("Certificate provided is not not in key store");
       }

Depending on the results of the search, a message is displayed to the user.

Removing an existing certificate from the key store

The following example demonstrates how to remove a certificate from the keyStore. Within the try...catch block, do the following:

        ...
        Enumeration enum = keyStore.elements();
        KeyStoreData data = null;
        while ( enum.hasMoreElements() ) {
		      data = (KeyStoreData) enum.nextElement();
              if ("My Certificate".equals( data.getLabel() ) ) {
	      }

Like in previous samples, a while loop is used to match the label of certificates in the keyStore with a given search String, in this case "myCertificate". Again, because more than one certificate can have the same label, you may need to prompt the user to determine which certificate to remove. Since there is only one certificate in the keyStore, we know this must be a match.

        }

        KeyStoreTicket ticket = data.getTicket();
        keyStore.removeKey(data, ticket);

        //let's see if we have removed the certificate.
        if ( keyStore.isMember(myNewCert) ) {
             System.out.println("Certificate provided is in the key store");
     	}
     	else {
             System.out.println("Certificate provided is not in key store");
     	}
        ...

The results of the search are displayed to the user.