How to use Java to perform ECC operations with the eHSM module

Last updated November 28, 2018

This example demonstrates how to use java in order to perform elliptic curve cryptography with the eHSM module using the standard SunPKCS11 provider.

For the full source code, refer to the github repository.

First, configure the SunPKCS11 provider with a .cfg file:

name = eHSM

# Modify the path of the eHSM shared library for your system
library = /usr/local/lib/libehsm.dylib
#library = /usr/local/lib/libehsm.so
#library = ehsh.dll

# if you have multiple eHSMs, change to the slot you want to use
slot = 0

Next, setup the PKCS#11 provider and login to the HSM:

    ...
    // Create PKCS11 Provider
    SunPKCS11 p = new SunPKCS11(configFileName);
    Security.addProvider(p);

    // Login to the eHSM
    KeyStore ks = KeyStore.getInstance("PKCS11", p);
    ks.load(null,args[0].toCharArray());
    ...

Generate a test key pair:

    // Generate an EC key pair
    // Notice the use of the provider to force generation on the eHSM instead of software.
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", p);
    ECGenParameterSpec kpgparams = new ECGenParameterSpec(curve);
    keyPairGenerator.initialize(kpgparams);
    System.out.println("Generating key pair.");
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

The curve parameter is one of the many supported curves, in this example it’s the NIST curves secp256r1 and secp384r1.

The java provider does not set the CKA_TOKEN attribute by default, so at this point the key pair is generated but only in session data (volatile memory in the eHSM). This default behaviour can be changed by adding a configuration entry to the provider config file (but it might not always be desirable - especially when using ephemeral keys):

attributes(generate, CKO_PRIVATE_KEY, *) = {
    CKA_TOKEN = true
}

Instead, the preferred way is to optionally use the keystore.setKeyEntry() method to store the key pair in permanent non-volatile storage when required. The java keystore requires a certificate to be stored with key pair entries in order to be found by the java keystore,
so here we create a self-signed certificate for this purpose:

    // Create a selfsigned certificate to store with the public key. This is a java keystore requirement.
    // the certificate is signed using the eHSM
    System.out.println("Creating self signed certificate.");
    X509Certificate cert = generateCert(
            keyPair,
            1,
            "SHA256withECDSA",
            "CN=example, L=Town, C=ZZ",
            null);
    ks.setKeyEntry(alias, keyPair.getPrivate(), null, new X509Certificate[]{cert});

Once the key pair is generated we can perform signing and verification operations:

    // sign some data
    Signature sig = Signature.getInstance(algo, p);
    sig.initSign(keyPair.getPrivate());
    byte[] data = "test".getBytes();
    sig.update(data);
    byte[] s = sig.sign();
    System.out.println("Signed with hardware key.");

    // verify the signature
    sig.initVerify(keyPair.getPublic());
    sig.update(data);
    if (!sig.verify(s)) {
        throw new Exception("signature did not verify");
    }
    System.out.println("Verified with hardware key.");

Subscribe to receive updates

* indicates required