OpenPGP KeyStore in Java

The KeyStore class defined by DidiSoft OpenPGP Library for Java is a composite storage for OpenPGP public and private keys.

In addition, the file based KeyStore protects the keys with a password.

NOTE: The KeyStore class is not to be confused wit the standard Java(tm)KeyStore

In this chapter we are going to introduce the basic operations with an OpenPGP KeyStore.

Table of contents:

1. Creating and opening a KeyStore
2. Importing keys
3. Exporting keys
4. Listing contained keys
5. Password check
6. Changing the password
7. Searching for a key

1. Creating and opening a KeyStore

Currently the library supports file based and memory located keystores.

The code lines below shows how to create file based and memory located keystores :

import com.didisoft.pgp.KeyStore;
...
// creates new or opens existing file based KeyStore
KeyStore keyStore = new KeyStore("examples/pgp.keystore", "keystore password");
 
// creates empty in-memory located KeyStore
KeyStore keyStore = new KeyStore();

NOTE: You may notice that no file is created after calling the file based constructor. In fact the file will be created after the first key is imported or generated.

More secure constructor

As of version 3.1.3 of the library and additional constructor method has been added to provide a custom key for encrypting in-memory of the KeyStore password. A real world implementation will usually obtain that key from a configuration file, but the example below just returns a hard coded value. For more information, please refer to the article regarding the Heap Inspection issue.

1
2
3
4
5
KeyStore ks = new KeyStore("my.keystore", "password", new ICustomKeyListener() {			
	public byte[] getKey(Object sender) {
		return new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14. 15, 16 };
	}
});

Naming convention

There is no naming convention for keystore files. We prefer the file name extension *.keystore, but you can choose your own.

2. Importing keys

Please check the chapter for importing keys for detailed examples.

3. Exporting keys

Please check the chapter for exporting keys for detailed examples.

4. Listing contained keys

The example below illustrates how to list the contents of a KeyStore in the console, with a similar output as the one produced by GnuPG (gpg –list-keys) and PGP(r) (pgp –list-keys)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import com.didisoft.pgp.*;
 
public class KeystoreListKeys {
 public static void main(String[] args) 
  throws java.IO.IOException, PGPException {	
    KeyStore keyStore = new KeyStore("/DataFiles/pgp.keystore", "changeit");		
 
    System.out.print("Type | Size | Key ID | User ID");
 
    KeyPairInformation[] keys = keyStore.getKeys();
    for (int i=0; i < keys.length; i++) {
	KeyPairInformation pair = keys[i];            
	System.out.print(pair.getAlgorithm());
	System.out.print(pair.getKeySize());
	System.out.print(pair.getKeyIDHex());
	for (int j=0; j < pair.getUserIDs().length; j++) {
		System.out.print(pair.getUserIDs()[j]);
	}           			
	System.out.println();
  }		
 }	
}

5. Password probing

Sometimes we may want to check the password of a KeyStore before opening it:

boolean passwordIsCorrect = KeyStore.checkPassword("c:\\openpgp.keystore", "password");

6. Changing the password of the KeyStore

The password of the KeyStore storage can be changed at runtime with KeyStore.setPassword.

KeyStore keyStore = new KeyStore("/DataFiles/pgp.keystore", "changeit");
keyStore.setPassword("new password");
keyStore.save(); // explicit save in order to apply the new password

7. Searching for a key

We can check is there a key with a given Key Id or User ID in a KeyStore instance:

  KeyStore keyStore = new KeyStore("pgp.keystore", "changeit");
  boolean keyExists = keyStore.containsKey("demo@didisoft.com");

Summary

In this chapter we have discussed the basic operations with the KeyStore object exposed by DidiSoft OpenPGP Library for Java.

List of methods used:

KeyStore() constructor for an in-memory KeyStore
KeyStore(fileName, password) constructor for a file based KeyStore
getKeys() returns array of KeyPairInformation instances for the contained keys
checkPassword(fileName, password) checks is a given password the correct one for a keystore file
setPassword(new_password) sets a new password for the keystore file
containsKey(userId) checks is there a key with the given User ID