Migrate your JCE provider from Client SDK 3 to Client SDK 5 - AWS CloudHSM

Migrate your JCE provider from Client SDK 3 to Client SDK 5

Use this topic to migrate your JCE provider from Client SDK 3 to Client SDK 5. For benefits on migrating, see Benefits of Client SDK 5.

In AWS CloudHSM, customer applications perform cryptographic operations using the AWS CloudHSM Client Software Development Kit (SDK). Client SDK 5 is the primary SDK that continues to have new features and platform support added to it.

The Client SDK 3 JCE provider uses custom classes and APIs that are not part of the standard JCE specification. Client SDK 5 for the JCE provider is complaint with the JCE specification and is backwards incompatible with Client SDK 3 in certain areas. Customer applications may require changes as part of the migration to Client SDK 5. This section outlines the changes required for a successful migration.

To review migration instructions for all providers, see Migrating from Client SDK 3 to Client SDK 5.

Prepare by addressing breaking changes

Review these breaking changes and update your application in your development environment accordingly.

The Provider class and name have changed

What has changed What it was in Client SDK 3 What it is in Client SDK 5 Example

Provider class and name

The JCE provider class in Client SDK 3 is called CaviumProvider and has the Provider name Cavium.

In Client SDK 5, the Provider class is called CloudHsmProvider and has the Provider name CloudHSM.

An example of how to initialize the CloudHsmProvider object is available in the AWS CloudHSM GitHub sample repository.

Explicit login has changed, implicit has not

What has changed What it was in Client SDK 3 What it is in Client SDK 5 Example

Explicit login

Client SDK 3 uses the LoginManager class for explicit login 1.

In Client SDK 5, the CloudHSM provider implements AuthProvider for explicit login. AuthProvider is a standard Java class and follows Java's idiomatic way to log in to a Provider. With improved login state management in Client SDK 5, applications no longer need to monitor and perform login during reconnections2.

For an example on how to use explicit login with Client SDK 5, see the LoginRunner sample in the AWS CloudHSM GitHub sample repository.

Implicit login

No changes are required for implicit login. The same properties file and all environment variables will continue to work for the implicit login when migrating from Client SDK 3 to Client SDK 5.

For an example on how to use implicit login with Client SDK 5, see the LoginRunner sample in the AWS CloudHSM GitHub sample repository.

  • [1] Client SDK 3 code snippet:

    LoginManager lm = LoginManager.getInstance(); lm.login(partition, user, pass);
  • [2] Client SDK 5 code snippet:

    // Construct or get the existing provider object AuthProvider provider = new CloudHsmProvider(); // Call login method on the CloudHsmProvider object // Here loginHandler is a CallbackHandler provider.login(null, loginHandler);

    For an example on how to use explicit login with Client SDK 5, see the LoginRunner sample in the AWS CloudHSM GitHub sample repository.

Key generation has changed

What has changed What it was in Client SDK 3 What it is in Client SDK 5 Example

Key generation

In Client SDK 3, Cavium[Key-type]AlgorithmParameterSpec is used to specify key generation parameters. For a code snippet, see footnote 1.

In Client SDK 5, KeyAttributesMap is used to specify key generation attributes. For a code snippet, see footnote 2.

For an example on how to use KeyAttributesMap to generate a symmetric key, see the SymmetricKeys sample in the AWS CloudHSM Github sample repository.

Key pair generation

In Client SDK 3, Cavium[Key-type]AlgorithmparameterSpec is used to specify key pair generation parameters. For a code snippet, see footnote 3.

In Client SDK 5, KeyPairAttributesMap is used to specify these parameters. For a code snippet, see footnote 4.

For an example on how to use KeyAttributesMap to generate an asymmetric key, see the AsymmetricKeys sample in the AWS CloudHSM GitHub sample repository.

  • [1] Client SDK 3 key generation code snippet:

    KeyGenerator keyGen = KeyGenerator.getInstance("AES", "Cavium"); CaviumAESKeyGenParameterSpec aesSpec = new CaviumAESKeyGenParameterSpec( keySizeInBits, keyLabel, isExtractable, isPersistent); keyGen.init(aesSpec); SecretKey aesKey = keyGen.generateKey();
  • [2] Client SDK 5 key generation code snippet:

    KeyGenerator keyGen = KeyGenerator.getInstance("AES", CloudHsmProvider.PROVIDER_NAME); final KeyAttributesMap aesSpec = new KeyAttributesMap(); aesSpec.put(KeyAttribute.LABEL, keyLabel); aesSpec.put(KeyAttribute.SIZE, keySizeInBits); aesSpec.put(KeyAttribute.EXTRACTABLE, isExtractable); aesSpec.put(KeyAttribute.TOKEN, isPersistent); keyGen.init(aesSpec); SecretKey aesKey = keyGen.generateKey();
  • [3] Client SDK 3 key pair generation code snippet::

    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("rsa", "Cavium"); CaviumRSAKeyGenParameterSpec spec = new CaviumRSAKeyGenParameterSpec( keySizeInBits, new BigInteger("65537"), label + ":public", label + ":private", isExtractable, isPersistent); keyPairGen.initialize(spec); keyPairGen.generateKeyPair();
  • [4] Client SDK 5 key pair generation code snippet:

    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", providerName); // Set attributes for RSA public key final KeyAttributesMap publicKeyAttrsMap = new KeyAttributesMap(); publicKeyAttrsMap.putAll(additionalPublicKeyAttributes); publicKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Public"); publicKeyAttrsMap.put(KeyAttribute.MODULUS_BITS, keySizeInBits); publicKeyAttrsMap.put(KeyAttribute.PUBLIC_EXPONENT, new BigInteger("65537").toByteArray()); // Set attributes for RSA private key final KeyAttributesMap privateKeyAttrsMap = new KeyAttributesMap(); privateKeyAttrsMap.putAll(additionalPrivateKeyAttributes); privateKeyAttrsMap.put(KeyAttribute.LABEL, label + ":Private"); // Create KeyPairAttributesMap and use that to initialize the // keyPair generator KeyPairAttributesMap keyPairSpec = new KeyPairAttributesMapBuilder() .withPublic(publicKeyAttrsMap) .withPrivate(privateKeyAttrsMap) .build(); keyPairGen.initialize(keyPairSpec); keyPairGen.generateKeyPair();

Finding, deleting, and referencing keys have changed

Finding an already generated key with AWS CloudHSM entails using the KeyStore. Client SDK 3 has two KeyStore types: Cavium and CloudHSM. Client SDK 5 only has one KeyStore type: CloudHSM.

Moving from the Cavium KeyStore to CloudHSM KeyStore requires a change of KeyStore type. Additionally, Client SDK 3 uses key handles to reference keys, while Client SDK 5 uses key labels. The resulting behavior changes are listed below.

What has changed What it was in Client SDK 3 What it is in Client SDK 5 Example

Key references

With Client SDK 3, applications use either key labels or key handles to reference keys in the HSM. They use labels with KeyStore to find a key, or they use handles and create CaviumKey objects.

In Client SDK 5, applications can use the Using AWS CloudHSM KeyStore Java class to find keys by label. To find keys by handle, use the AWS CloudHSM KeyStoreWithAttributes with AWS CloudHSM KeyRefereneSpec.

Finding multiple entries

When searching for a key using getEntry, getKey, or getCertificate in scenarios where multiple items with the same critera exist in the Cavium KeyStore, only the first entry found will be returned.

With the AWS CloudHSM KeyStore and KeyStoreWithAttributes, this same scenario will result in an exception being thrown. To fix this problem, it is recommended to set unique labels for keys using the key set-attribute command in CloudHSM CLI. Or use KeyStoreWithAttributes#getKeys to return all keys that match the critera.

Find all keys

It is possible in Client SDK 3 to find all keys in the HSM using Util.findAllKeys().

Client SDK 5 makes finding keys simpler and more efficient by using the KeyStoreWithAttributes class. When possible, cache your keys to minimize latency. For more information, see Effectively manage keys in your application. When you need to retrieve all keys from the HSM, use KeyStoreWithAttributes#getKeys with an empty KeyAttributesMap.

An example that uses the KeyStoreWithAttributes class to find a key is available in the AWS CloudHSM Github sample repository and a code snippet is shown in 1.

Key deletion

Client SDK 3 uses Util.deleteKey() to delete a key.

The Key object in Client SDK 5 implements the Destroyable interface which allows for keys to be deleted using the destroy() method of this interface.

An example code showing the delete key functionality can be found on the CloudHSM Github sample repository. A sample snippet for each SDK is shown in 2.

  • [1] a snippet is shown below:

    KeyAttributesMap findSpec = new KeyAttributesMap(); findSpec.put(KeyAttribute.LABEL, label); findSpec.put(KeyAttribute.KEY_TYPE, keyType); KeyStoreWithAttributes keyStore = KeyStoreWithAttributes.getInstance("CloudHSM"); keyStore.load(null, null); keyStore.getKey(findSpec);
  • [2] Deleting a key in Client SDK 3:

    Util.deleteKey(key);

    Deleting a key in Client SDK 5:

    ((Destroyable) key).destroy();

Cipher unwrap operations have changed, other cipher operations have not

Note

No changes are required for Cipher encrypt/decrypt/wrap operations.

Unwrap operations require the Client SDK 3 CaviumUnwrapParameterSpec class to be replaced with one of the following classes specific to the cryptographic operations listed.

  • GCMUnwrapKeySpec for AES/GCM/NoPadding unwrap

  • IvUnwrapKeySpec for AESWrap unwrap and AES/CBC/NoPadding unwrap

  • OAEPUnwrapKeySpec for RSA OAEP unwrap

Example snippet for OAEPUnwrapkeySpec:

OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec( "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSpecified.DEFAULT); KeyAttributesMap keyAttributesMap = new KeyAttributesMap(KeyAttributePermissiveProfile.KEY_CREATION); keyAttributesMap.put(KeyAttribute.TOKEN, true); keyAttributesMap.put(KeyAttribute.EXTRACTABLE, false); OAEPUnwrapKeySpec spec = new OAEPUnwrapKeySpec(oaepParameterSpec, keyAttributesMap); Cipher hsmCipher = Cipher.getInstance( "RSA/ECB/OAEPPadding", CloudHsmProvider.PROVIDER_NAME); hsmCipher.init(Cipher.UNWRAP_MODE, key, spec);

Signature operations have not changed

No changes are required for Signature operations.

Migrate to Client SDK 5

Follow the instructions in this section to migrate from Client SDK 3 to Client SDK 5.

Note

Amazon Linux, Ubuntu 16.04, Ubuntu 18.04 CentOS 6, CentOS 8, and RHEL 6 are not currently supported with Client SDK 5. If you are currently using one of these platforms with Client SDK 3, you will need to choose a different platform when migrating to Client SDK 5.

  1. Uninstall the JCE provider for Client SDK 3.

    Amazon Linux 2
    $ sudo yum remove cloudhsm-jce
    CentOS 7
    $ sudo yum remove cloudhsm-jce
    RHEL 7
    $ sudo yum remove cloudhsm-jce
    RHEL 8
    $ sudo yum remove cloudhsm-jce
  2. Uninstall the Client Daemon for Client SDK 3.

    Amazon Linux 2
    $ sudo yum remove cloudhsm-client
    CentOS 7
    $ sudo yum remove cloudhsm-client
    RHEL 7
    $ sudo yum remove cloudhsm-client
    RHEL 8
    $ sudo yum remove cloudhsm-client
    Note

    Custom configurations need to be enabled again.

  3. Install the Client SDK JCE provider by following the steps in Install and use the AWS CloudHSM JCE provider for Client SDK 5.

  4. Client SDK 5 introduces a new configuration file format and command-line bootstrapping tool. To bootstrap your Client SDK 5 JCE provider, follow the instructions listed in the user guide under Bootstrap the Client SDK.

  5. In your development environment, test your application. Make updates to your existing code to resolve your breaking changes before your final migration.

Related topics