Coder Social home page Coder Social logo

aws-cloudhsm-jce-examples's Introduction

aws-cloudhsm-jce-examples

These sample applications demonstrate how to use the JCE with CloudHSM. They show basic functionality, as well as best practices regarding performance.

License Summary

This sample code is made available under a modified MIT license. See the LICENSE file.

Building the examples

Dependencies

The latest SDK5 version of CloudHSM JCE is required. They should be installed using the official procedures documented here:

The examples are tested on a fresh Amazon Linux 2 AMI. You will need to have the following packages installed:

  • OpenJDK 8
  • Apache Maven 3.0.5

You can install these packages on Amazon Linux 2 by running

sudo yum install -y java-1.8.0-amazon-corretto-devel maven

If you are running on Amazon Linux 1, you will need to install extra packages to get Maven. You can follow these instructions to build the samples on Amazon Linux 1:

# Maven is only available through extra packages
sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo

# You will need Java 1.8 to build the samples
sudo yum install -y java-1.8.0-openjdk-devel
sudo yum install -y apache-maven

# When updating alternatives, choose the 1.8 path: /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java
sudo update-alternatives --config java

Building

You can build the project using Maven. Maven will copy the required CloudHSM jars into a local repository and build fat jars which can be executed from the command line. These fat jars will be placed in the target/assembly/ directory.

Before you build your project, be sure to enter the correct CloudHSM version number based on which CloudHSM JCE Provider you have installed on your system. By default, this project is set to use the latest available CloudHSM version, and you may need to make modifications if you are running an older version (note that not all tests are guaranteed to work with older versions of the client). To do this, modify the following line in the pom.xml to match your version:

<cloudhsmVersion>5.5.0</cloudhsmVersion>

To build the project, use the following command:

mvn validate
mvn clean package

Running the samples

You will need to have a CloudHSM Client connected to an ACTIVE cluster. For more details, please follow the official instructions here:

You will need to provide credentials to the JCE provider in order to run the samples. Please read about JCE provider credentials here:

All Java dependencies should be bundled in the fat jars. Jars can be run using the following command line (as an example):

java -ea -jar target/assembly/login-runner.jar --help

Running and verifying all the samples

To run and verify all the samples together, run the command mvn verify

aws-cloudhsm-jce-examples's People

Contributors

amit-l avatar bnjsmt avatar dmallare avatar drjerry avatar gmudambi avatar jpeddicord avatar kladd avatar mayank-amzn avatar mayankambaliya avatar nikran-amzn avatar palmep avatar rday avatar shivam-amzn avatar shrutikamtekar avatar theempty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-cloudhsm-jce-examples's Issues

Is there any EC key import and ECSDA with secpk1 example ?

I was trying to generate EC key with secpk1, but when I try to sign with this key, the signature I got was not signed by secpk1 curve ???

  public static byte[] sign(byte[] message, PrivateKey key, String signingAlgorithm)
      throws SignatureException, InvalidKeyException, NoSuchAlgorithmException,
      NoSuchProviderException {
    java.security.Signature sig = java.security.Signature.getInstance(signingAlgorithm, "Cavium");
    sig.initSign(key);
    sig.update(message);
    return sig.sign();
  }

there is no any place for us to chose sign curve ???
any example of secpk1 sign ??

More realistic symmetric key export example

A common key exchange operation is that a "client" provides a public (RSA or EC) key to the HSM, the HSM generates a symmetric key encrypted under that public key, and the client then imports the symmetric key into its own keystore. (This is a toy example of how key exchange between HSMs and mobile devices works.) The existing code samples provide hints at how to accomplish each of these steps except importing the public key; RSAImportKey does something similar but in the opposite direction.

An end-to-end example for exporting an AES key using this flow would be welcome.

Trying to run SDK 5 fat jar. Getting a JNI error - java.lang.UnsatisfiedLinkError

This is on RHEL 7. I've installed cloudhsm JCE 5.6.0:

$ rpm -qa | grep cloud
cloudhsm-jce-5.6.0-1.el7.x86_64

I also ran the configure-jce step:

$ sudo /opt/cloudhsm/bin/configure-jce -a $HSM_IP

Is there something else to install to get the shared libraries for SDK 5?

When I try to run the fat jar built with Maven from the Github repo (on sdk5 branch), I get this:

java -ea -jar login-runner.jar --method explicit --user user --password pass
Exception in thread "main" java.lang.ExceptionInInitializerError
	at com.amazonaws.cloudhsm.examples.LoginRunner.loginWithExplicitCredentials(LoginRunner.java:113)
	at com.amazonaws.cloudhsm.examples.LoginRunner.main(LoginRunner.java:90)
Caused by: com.amazonaws.cloudhsm.jce.jni.exception.InternalException: Failed to load cloudhsm_jce native library. Error: java.lang.UnsatisfiedLinkError: /tmp/CloudHsmNativeLibraryTemporaryDir7438679742437118261/libcloudhsm_jce.so: /tmp/CloudHsmNativeLibraryTemporaryDir7438679742437118261/libcloudhsm_jce.so: failed to map segment from shared object: Operation not permitted
	at com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider.<clinit>(CloudHsmProvider.java:539)
	... 2 more
Caused by: java.lang.UnsatisfiedLinkError: /tmp/CloudHsmNativeLibraryTemporaryDir7438679742437118261/libcloudhsm_jce.so: /tmp/CloudHsmNativeLibraryTemporaryDir7438679742437118261/libcloudhsm_jce.so: failed to map segment from shared object: Operation not permitted
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817)
	at java.lang.Runtime.load0(Runtime.java:810)
	at java.lang.System.load(System.java:1088)
	at com.amazonaws.cloudhsm.jce.provider.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:53)
	at com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider.<clinit>(CloudHsmProvider.java:535)
	... 2 more

Import EC Key Issue

Hi,

I am trying to import an EC Private Key using the Keystore.SetKeyEntry() method. But the key is not being persistent. Can you please provide samples of setting the key attributes for keystore examples?

Alternatively is there a way to generate an EC Private key with curve params EC_CURVE_SECP521 and a custom point on the curve? Right now if i specify an EC_POINT attribute i am getting an AddAttributeException with an Unsupported Attribute error.

Please advice.

Thanks
Narasimha

KeyStore examples not working

I'm having a look at the examples after creating an HSM cluster. Most of them work well, except the examples using KeyStore, in those cases I always get an exception like this one:

Exception in thread "main" java.security.KeyStoreException: CloudHSM not found
	at java.base/java.security.KeyStore.getInstance(KeyStore.java:871)
	at com.amazonaws.cloudhsm.examples.AESCBCEncryptDecryptRunner.getKeyByLabel(AESCBCEncryptDecryptRunner.java:82)
	at com.amazonaws.cloudhsm.examples.AESCBCEncryptDecryptRunner.main(AESCBCEncryptDecryptRunner.java:54)
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: CloudHSM, provider: CloudHSM, class: com.amazonaws.cloudhsm.jce.provider.CloudHsmKeyStore)
	at java.base/java.security.Provider$Service.newInstance(Provider.java:1868)
	at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
	at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
	at java.base/java.security.Security.getImpl(Security.java:701)
	at java.base/java.security.KeyStore.getInstance(KeyStore.java:868)
	... 2 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.security.KeyStoreSpi java.security.KeyStore.keyStoreSpi accessible: module java.base does not "opens java.security" to unnamed module @39fb3ab6
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at com.amazonaws.cloudhsm.jce.provider.CloudHsmKeyStore.getSpiFromKeyStore(CloudHsmKeyStore.java:96)
	at com.amazonaws.cloudhsm.jce.provider.CloudHsmKeyStore.<init>(CloudHsmKeyStore.java:123)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at java.base/java.security.Provider$Service.newInstanceOf(Provider.java:1879)
	at java.base/java.security.Provider$Service.newInstanceUtil(Provider.java:1886)
	at java.base/java.security.Provider$Service.newInstance(Provider.java:1861)
	... 6 more

I have tried to run this example using different versions of the JDK (8, 11, 17), and also installing a previous version of the JCE provider (5.4.0), as the latest version now is 5.5.0, but I'm always getting the same result.

Is there anything I'm missing here?

Explicit login not working

Hi I am building a application that connects to cloud HSM using JCE client SDK 5. I am trying to do explicit login but it is getting failed.
I am passing the creds correctly to the method.
I am getting a null provider from this statement -
provider = (AuthProvider) Security.getProvider(CloudHsmProvider.PROVIDER_NAME); and then its trying to do implicit login using the below block which check for null provider.

            if (provider == null) {
                provider = new CloudHsmProvider();
            }

Pls, let me know what I am missing in this process.

com.amazonaws.cloudhsm.jce.jni.exception.FailedLoginException: Incorrect credentials are passed for this operation: Incorrect authentication credentials.
at com.amazonaws.cloudhsm.jce.jni.Session.do_login(Native Method)
at com.amazonaws.cloudhsm.jce.jni.Session.login(Session.java:22)
at com.amazonaws.cloudhsm.jce.provider.LoginManager.login(LoginManager.java:88)
at com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider.login(CloudHsmProvider.java:666)
at com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider.attemptImplicitLogin(CloudHsmProvider.java:621)
at com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider.(CloudHsmProvider.java:165)
at one.card.rest.cloud.aws.services.LoginRunner.loginWithExplicitCredentials(LoginRunner.java:98)

LoginManger dependency on log4j

I am getting the below bean creation failure as the cavium LoginManager is unable to find reference to log4j.LogManager.

Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
...

  | Caused by: java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
  |     at com.cavium.cfm2.LoginManager.<clinit>(LoginManager.java:172)

I checked that I have the log4j available. We use slf4j as the logging wrapper, but dont think that will cause an issue.

This happens during the deployment time when the service starts.
I also made sure that the log4j-core-2.9.1.jar exists in our deployment .war file.

Is it possible that LoginManager has very strong dependency on one particlar ver. of log4j?

Unable find the generated key in AWS cloud HSM

Ran the following command from the JCE Provider:
java -jar key-utility-runner.jar --import-key
output:
[cloudhsm_provider::hsm1::session::key_management::provider_key_builder::create_key_internal] Key created on the HSM with handle: 655385(0x000A0019)

command:
java -jar key-utility-runner.jar --label Test --get-key
output:
Could not find the given key label Test

unable to find the key from AWS CLI also
Command: findKey

    Total number of keys present: 18

    Number of matching keys from start index 0::17

    **Handles of matching keys:
    6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 524305, 524306, 524307, 524308,
    524309, 524310, 524311**

    Cluster Status:
    Node id 2 status: 0x00000000 : HSM Return: SUCCESS

    Cfm3FindKey returned: 0x00 : HSM Return: SUCCESS

Importing keys from PEM files

Hi there,

I think it would be very useful including a feature in KeyUtilitiesRunner.java making it able to import keys from PEM files. Would it be possible?

Thank you,
Eduardo Suzuki.

Login Methods Other Than 'explicit' Not Working

Hi Ryan,

Avni asked me to file this issue. We're (Adobe) trying to build/test the samples against our HSM instance, and I'm only able to get things working use the 'explicit' method. If I attempt to use 'system-properties' or 'environment', then all of the samples fail with "Exception in thread "main" java.security.NoSuchProviderException: JCE cannot authenticate the provider Cavium". Also, I've set up an 'HsmCredentials.properties' file, and it doesn't seem to get used/found either.

What this means is that doing the 'mvn verify' step listed in the README always fails even if I have the HSM_USER, HSM_PASSWORD, and HSM_PARTITION environment vars set (or if I have the HsmCredentials.properties file specified in my $CLASSPATH with those entities set). I can get login-runner.jar to work if I set all of the 'explicit' params. I can't get any of the other samples to work because only LoginRunner seems to use the LoginManager. All of the other samples seem to reply on the implicit mechanisms.

Issue with CaviumKeyStore its logging configuration

Given that Spring Boot uses SLF4j for logging, we are getting issues with the org.apache.logging.log4j.core.Logger defined in the CaviumKeyStore class at line 40:
private static final Logger logger = (Logger)LogManager.getLogger("CaviumKeyStore");
So we were wondering: is it possible to create a version in which there is no such logger defined or taken up from the context?

CloudHSM sign in and sign out problem

We are using the latest CloudHSM sdk 5 for java. We are creating the connection to it using AWS lambdas and the sign in and out is being done with the same code as the code examples that are in this repo.
We are getting a problem when using a warm environment, as when trying to do the sign in it gives us the following error:

"message": "The underlying Provider connection was lost: Underlying connection to provider was lost",
"name": "com.amazonaws.cloudhsm.jce.jni.exception.ProviderException",

When its a cold environment when dont have this problem as it does sign in and out, but when reusing it we get this exception. We are using loginWithExplicitCredentials

KeyStore should return only one key for the provided alias aesAlias

Hi,
I am using the examples in here to try to see if cloud HSM maes sense for me.
Stating with a simple use case, I simply want to be able to store an AES key in a key store and retreive it.

I obviously wantrto cipher / decipher, but I am facing an issue before that.

After initial keystore and key creation, I reload a brand new keystore and want to use that one to "prove" I can retreive an previsously stored key.

I am able to see the alias I just created, but when I try to "getKey()", I am getting this error:

Exception in thread "main" java.security.UnrecoverableKeyException: KeyStore should return only one key for the provided alias aesAlias

Any Idea what I am doing wrong ?

Note: in order for the code tu run I had to add the VM arg as suggested here.

package com.redacted.commons.tests;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.util.Enumeration;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import com.amazonaws.cloudhsm.jce.jni.exception.AddAttributeException;
import com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider;
import com.amazonaws.cloudhsm.jce.provider.attributes.KeyAttribute;
import com.amazonaws.cloudhsm.jce.provider.attributes.KeyAttributesMap;


public class AwsCloudHSMTest2 {

	static String keyStorePath = "D:\\Temp\\AwsCloudHsm\\awskeystore2.awks";
	static String keyStorePassword = "password";
	static String awsUser = "user";
	static String awsPassword = "password";

	static String aesAlias = "aesAlias";
	static String rsaAlias = "rsaAlias";

	public static void main(String[] args) throws Exception {

		System.out.println("Start");

		System.out.println("Listing Keys / login");

		System.setProperty("HSM_USER", awsUser);
		System.setProperty("HSM_PASSWORD", awsPassword);
		Security.addProvider(new CloudHsmProvider());

		System.out.println("Creating keystore if it doesnt exist");

		KeyStore ks = null;

		try {

			ks = KeyStore.getInstance(CloudHsmProvider.PROVIDER_NAME);
			ks.load(null, keyStorePassword.toCharArray());

		} catch (Exception e) {
			e.printStackTrace();
			System.err.println(e);

		}

		System.out.println("Creating AES Key");

		SecretKey sk = (SecretKey) generateAESKey(256, aesAlias);

		System.out.println("sk.getAlgorithm(): " + sk.getAlgorithm());
		
		// here I will be doing ciphering

		ks.setKeyEntry(aesAlias, sk, keyStorePassword.toCharArray(), null);

		System.out.println("AES Key set in KS - now saving");

		// saving the keystore

		FileOutputStream out = null;

		try {

			out = new FileOutputStream(keyStorePath);
			ks.store(out, keyStorePassword.toCharArray());
			out.close();

		} catch (Exception e) {
			e.printStackTrace();
			System.err.println(e);

		}

		// useless, but I like to see that anyways
		
		ks = null;
		sk = null;

		// reading key from keystore

		KeyStore ks2 = loadKeyStore(keyStorePath, keyStorePassword);

		listKeys(ks2);

		Key retrievedKey = ks2.getKey(aesAlias, null);

		System.out.println("Retrieved AES Key");
		System.out.println("sk2.getAlgorithm(): " + retrievedKey.getAlgorithm());

		// here I will be doing deciphering
		
	}

	public static Key generateAESKey(int keySizeInBits, String keyLabel) throws InvalidAlgorithmParameterException,
			NoSuchAlgorithmException, NoSuchProviderException, AddAttributeException {
		return generateAESKey(keySizeInBits, keyLabel, new KeyAttributesMap());
	}

	public static Key generateAESKey(int keySizeInBits, String keyLabel, KeyAttributesMap aesSpecKeyAttributes)
			throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException,
			AddAttributeException {

// Create an Aes keygen Algorithm parameter spec using KeyAttributesMap
		final KeyAttributesMap aesSpec = new KeyAttributesMap();

		aesSpec.putAll(aesSpecKeyAttributes);
		aesSpec.put(KeyAttribute.LABEL, keyLabel);
		aesSpec.put(KeyAttribute.SIZE, keySizeInBits);

		KeyGenerator keyGen = KeyGenerator.getInstance("AES", CloudHsmProvider.PROVIDER_NAME);
		keyGen.init(aesSpec);
		SecretKey aesKey = keyGen.generateKey();

		return aesKey;
	}

	public static KeyStore loadKeyStore(String path, String password) throws KeyStoreException {

		final KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.CLOUDHSM_KEYSTORE_TYPE);
		try {
			final FileInputStream instream = new FileInputStream(new File(path));
			// This call to keyStore.load() will open the CloudHSM keystore file with the
			// supplied
			// password.
			keyStore.load(instream, password.toCharArray());
		} catch (final IOException | NoSuchAlgorithmException | CertificateException ex) {
			System.err.println("Keystore not found, loading an empty store");
		}

		return keyStore;
	}

	public static void saveKeyStore(String path, String password, KeyStore keyStore) {

		FileOutputStream out = null;

		try {

			out = new FileOutputStream(path);
			keyStore.store(out, password.toCharArray());
			out.close();

		} catch (Exception e) {

			System.err.println(e);

		}

	}

	public static void listKeys(KeyStore keyStore) throws Exception {

		final Enumeration<String> aliases = keyStore.aliases();

		System.out.println("Listing KS ");
		while (aliases.hasMoreElements()) {

			String alias = (String) aliases.nextElement();

			System.out.println("Alias: " + alias);

		}

	}

}

Why the AWS local keystore file has symmetric and asymmetric keys?

I generated a keypair in Cloud HSM by giving a keystore file.
I downloaded the keystore file and opened it in keystore explorer and I see symmetric and asymmetric key entries. As per AWS documentation, only the certificate corresponding to keypair is stored in the local keystore file.

I exported the private key but it is not complete.
As the expected public is exportable and complete.

I assume, Cloud HSM maintains a reference to all the entries with partial key info. Is it correct?

Generate keypair with a certificate with store file

keytool -genkeypair -alias alias1  -keystore /home/user/my_cloudhsm/my-cloudhsm.store "CN=alias1.example.com, OU=Research, O=Acme, L=XYZ, ST=CA, C=US" -storetype CLOUDHSM  -storepass password -keyalg rsa -keysize 2048 -sigalg sha512withrsa -validity 360  -dname  -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib

The underlying Provider connection was lost (JCE provider 5.11.0 )

I'm encountering an issue where I'm unable to retrieve keys intermittently. The error message states: "Failed to retrieve key: The underlying Provider connection was lost: Communication with the device was lost during the execution of the function." It appears to happen randomly and inconsistently.
I am running a cluster containing two HSMs. In my java application, the provider is initialized properly using system properties provided credentials .
What could be the reason ?

Issue with generateECKeyPairWithParams and generateRSAKeyPairWithParams

java.lang.NoClassDefFoundError: Could not initialize class com.cavium.key.CaviumRSAPrivateKey
at com.cavium.cfm2.Generator.generateRSAKeyPair(Generator.java:97) ~[cloudhsm-2.0.3.jar!/:na]
at com.cavium.key.generator.CaviumRSAKeyPairGenerator.generateKeyPair(CaviumRSAKeyPairGenerator.java:71) ~[cloudhsm-2.0.3.jar!/:na]
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:697) ~[na:1.8.0_212]
at com.sabre.awshsmconnector.AsymmetricKeys.generateRSAKeyPairWithParams(AsymmetricKeys.java:93) ~[classes!/:0.0.1-SNAPSHOT]
at com.sabre.awshsmconnector.AsymmetricKeys.generateRSAKeyPair(AsymmetricKeys.java:82) ~[classes!/:0.0.1-SNAPSHOT]
at com.sabre.awshsmconnector.RSAOperationsRunner.encryptRSA(RSAOperationsRunner.java:147) ~[classes!/:0.0.1-SNAPSHOT]
at com.sabre.awshsmconnector.LoginHSM.loginHSMEncryptData(LoginHSM.java:92) ~[classes!/:0.0.1-SNAPSHOT]
at com.sabre.awshsmconnector.AwsController.encryptedResponse(AwsController.java:17) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_212]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_212]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_212]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.6.RELEASE.jar!/:5.1.6.RELE


java.lang.NoClassDefFoundError: Could not initialize class com.cavium.key.generator.CaviumECKeyPairGenerator
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_212]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_212]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_212]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_212]
at java.security.Provider$Service.newInstance(Provider.java:1595) ~[na:1.8.0_212]
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236) ~[na:1.8.0_212]
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206) ~[na:1.8.0_212]
at java.security.KeyPairGenerator.getInstance(KeyPairGenerator.java:279) ~[na:1.8.0_212]
at com.sabre.awshsmconnector.AsymmetricKeys.generateECKeyPairWithParams(AsymmetricKeys.java:55) ~[classes!/:0.0.1-SNAPSHOT]
at com.sabre.awshsmconnector.AsymmetricKeys.generateECKeyPair(AsymmetricKeys.java:49) ~[classes!/:0.0.1-SNAPSHOT]

"True" RNG

Hello!

This is not an issue, but rather a support request. I didn't find a better place to post it, so please feel free to point me in the right direction and close this ticket if such place exists!

We are already using the Cavium JCE Provider to perform different cryptographic operations in the AWS CloudHSM in our backend systems. Now we want to use it for "true" random number generation.

Our current assumption is that access to the HSM's RNG is possible using the SecureRandom JCE class. However, the Java documentation states that "Many SecureRandom implementations are in the form of a pseudo-random number generator (PRNG) […]", so it is not clear to us whether the following code is going to get "true" randomness from the HSM, or instead is going to use a (possibli HSM-seeded) pseudo-RNG.

SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
// or, alternatively
byte seed[] = random.generateSeed(20);

I have been surfing through the AWS CloudHSM documentation and could not find any clear reference to it.
So, in a nutshell, my questions would be:

  • Is any of the methods above (nextBytes() or generateSeed()) using raw data from the HSM?
  • If the answer to the previous question is "no", then: which is the right way to generate true randoms using the Cavium JCE API?

Many thanks in advance!
Marc

Question: Need clarifications AWS Cloud HSM architecture

I am not sure if this is the right forum.

My apologies for the long post.

I read on AWS docs that, when keys are generated using java keytool, the certificates are stored in a local store file and the actual private key material is stored in Cloud HSM.

Generate keypair with a certificate without store file

keytool -genkeypair -alias alias1 "CN=alias1.example.com, OU=Research, O=Acme, L=XYZ, ST=CA, C=US" -storepass password -keyalg rsa -keysize 2048 -sigalg sha512withrsa -validity 360 -storetype CLOUDHSM -dname  -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib

Is there a default location where the default local store file is created?

When I execute the list command using java keytool, I am getting all the keys I added, and some how it is able to access the default store file.

Listing all alias without store file

keytool -list  -v -storetype CLOUDHSM -storepass password -keystore -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib/

If I generate keys passing keystore option then the certificate is getting stored in the store file as expected.

Generate keypair with a certificate with store file

keytool -genkeypair -alias alias1  -keystore /home/user/my_cloudhsm/my-cloudhsm.store "CN=alias1.example.com, OU=Research, O=Acme, L=XYZ, ST=CA, C=US" -storetype CLOUDHSM  -storepass password -keyalg rsa -keysize 2048 -sigalg sha512withrsa -validity 360  -dname  -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib

Listing all alias without store file

keytool -list  -keystore /home/user/akana_cloudhsm/eap-cloudhsm.store -v -storetype CLOUDHSM -storepass password  -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib/

But when I execute the list command with the keystore option it is returning all the aliases from all the keystores. I am expecting keys only from my-cloudhsm.store.

Why is this happening?

I downloaded my-cloudhsm.store and opened it in keystore explorer and I see symmetric keys, trusted certs and public-private keys pairs all in that store file. As per documentation I should see only certificates corresponding to keypairs and any imported trusted certificates.

I am also able to export the private key from the store file, but as expected the private key is not complete.

Symmetric keys, Trusted certs and public-private keys pairs

enter image description here

Exporting private key

enter image description here

Private key is not complete

enter image description here

My understanding is, CloudHSM maintains a local store file and has references to all the items added, including asymmetric keypairs, and symmetric keys but the actual key material is stored in Cloud HSM.

If this is correct, then if I have 3 applications running on 3 different machines accessing Cloud HSM then this local file needs to be synced on all 3 machines or copy the store file to an external file system and mount that onto all 3 machines?

Questions

  1. Why/how list returns all aliases from all the store files even when a particular file is passed?
  2. Java integration with Cloud HSM work with only store file (some input stream). I can not have different applications read directly from Cloud HSM without syncing the store file.
  3. Is there an inbuilt mechanism to sync the store file on all machines?
  4. Is it an idea to have a dedicated machine to manage keys(generate, delete) and sync the store file to all the applications?

Possible use of the CaviumKeyStore in client-side TLS

In order to keep the client-side TLS private key in the Cavium keystore, we made a wrapperkeystore at which we keep the certificate, so that we can actually use it to do client-side TLS. Are there actual issues with picking up client-side TLS authentication by the cavium hsm?

Update each example with authentication details.

Each example's module comment should include a short note about the authentication method. These samples use implicit authentication through environment variables. The comment should point to the README, and the README should link to the LoginRunner example and the public documentation where authentication is discussed.

CMAC Calculation using AWS HSM java SDK (JCE)

I would like to generate CMAC using AWS HSM java SDK

I would like to calculate CMAC value according to attached file out of method available which method i should use to calculate CMAC earlier i had used digest method but when I compared the result with online CMAC generator it was not matching with CMAC generated programmatically Need your assistance here

Please have a look at my below code and tell me which method I should use

package com.trimble.crypto.cmac;

import com.amazonaws.cloudhsm.jce.provider.CloudHsmProvider;
import com.trimble.crypto.util.IntializeCloudHSM;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.macs.CMac;
import org.bouncycastle.crypto.params.KeyParameter;

import javax.crypto.;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.
;
import java.util.Base64;

public class CMACCalculator {

private static final String ALGORITHM = "AESCMAC";

public  static byte[] digest(byte[] message, Key key, String algorithm, String provider)
        throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException {
    Mac mac = Mac.getInstance(algorithm, provider);
    mac.init(key);
    mac.update(message);

    return mac.doFinal();
}

public  static byte[] generateCMAC(Key key , byte[] fileContent) throws Exception {

    IntializeCloudHSM.intializeCloudHSM();
   // Key key = SymmetricKeys.getKeyByLabel(label);

    byte[] cmac = calculateCMAC(key.getEncoded(), fileContent);

    byte[] combined = new byte[cmac.length + fileContent.length];
    System.out.println("CloudHSM CMAC for file is *********= " + Base64.getEncoder().encodeToString(cmac));
    ByteBuffer byteBuffer = ByteBuffer.wrap(combined);
    byteBuffer.put(cmac);
    byteBuffer.put(fileContent);
    combined = byteBuffer.array();

    return combined;
}

// CMAC Functions
public  static byte[] generateCMAC(byte[] key, byte[] msg) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding",  CloudHsmProvider.PROVIDER_NAME);
    SecretKeySpec secretKeySpec = new SecretKeySpec(key, ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    return cipher.doFinal(msg);
}

private static byte[] calculateCMAC(byte[] keyBytes, byte[] data) throws Exception {
    BlockCipher cipher = new AESEngine();
    CMac cmac = new CMac(cipher);

    KeyParameter key = new KeyParameter(keyBytes);
    cmac.init(key);

    cmac.update(data, 0, data.length);

    byte[] result = new byte[cmac.getMacSize()];
    cmac.doFinal(result, 0);

    return result;
}

}

cloudhsm maven dependency out of date

Replication

  1. Successfully installed the JCE Provider.
  2. Ran ls -l /opt/cloudhsm/java/, which listed cloudhsm-3.4.0.jar, among other artifacts.
  3. Cloned the aws-cloudhsm-jce-examples repo with HEAD -> 62a9089.
  4. Ran cd aws-cloudhsm-jce-examples && mvn validate which issued the following error:
[INFO] --- maven-install-plugin:2.5.1:install-file (install-cloudhsm-jce) @ aws-cloudhsm-jce-examples ---
[ERROR] The specified file '/opt/cloudhsm/java/cloudhsm-3.1.2.jar' not exists

Resolution

I was able to update the version in the pom file locally.

I am happy to issue a PR with a 1-line change if the maintainers would like; I've noticed previous PRs like this bump versions in many of the maven dependencies, not just cloudhsm.

KeyUtilitiesRunner.java importRSAKey reproting this error. Attirbutes being specified are imcomplete

Exception in thread "main" com.amazonaws.cloudhsm.jce.jni.exception.AttributeException: Attributes being specified are incomplete: Incomplete template
at com.amazonaws.cloudhsm.jce.jni.RsaPrivateKeyImportBuilder.do_importKey(Native Method)
at com.amazonaws.cloudhsm.jce.jni.RsaPrivateKeyImportBuilder.importKey(RsaPrivateKeyImportBuilder.java:35)
at com.amazonaws.cloudhsm.jce.provider.ImportKey.importRsaPrivateKey(ImportKey.java:168)
at com.amazonaws.cloudhsm.jce.provider.RsaKeyFactory.engineGeneratePrivate(RsaKeyFactory.java:153)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:366)
at com.amazonaws.cloudhsm.examples.KeyUtilitiesRunner.importRsaKey(KeyUtilitiesRunner.java:268)
at com.amazonaws.cloudhsm.examples.KeyUtilitiesRunner.main(KeyUtilitiesRunner.java:147)

Library docs

Any source or docs, ideally Javadoc, available for the cloudhsm library? For example, I want to do the equivalent of 'findKey -t key_type', which I assume can be done with the Util.findKeys(String, int, int, int, byte[], Vector) method or similar but it's impossible to know what those parameters actually are although one of those ints is presumably the type. Similarly with other parts of the API, it's not clear what some of the methods do and what they take.

Specific points I'm trying to figure out:

  1. How to find keys based on type (AES, EC etc.), class etc..
  2. How to find all keys (Util.findAllKeys(null) does that return everything?).

Example for KeyAttributes/Properties

Hi,

We are trying to migrate from CloudHSM Client v3.x to v5.x and we were using the CaviumKey to get all the key properties like

key.isPersistent()
key.isExtractable()
key.getAlgorithm()
key.getSize()
key.getLabel()

The KeyUtilitiesRunner.java in master has the below implementation.

private static void displayKeyInfo(CaviumKey key) {
        if (null != key) {
            System.out.printf("Key handle %d with label %s\n", key.getHandle(), key.getLabel());
            // Display whether the key can be extracted from the HSM.
            System.out.println("Is Key Extractable? : " + key.isExtractable());

            // Display whether this key is a token key.
            System.out.println("Is Key Persistent? : " + key.isPersistent());

            // The algorithm and size used to generate this key.
            System.out.println("Key Algo : " + key.getAlgorithm());
            System.out.println("Key Size : " + key.getSize());
        }
    }

Can you please provide a similar sample for SDK5

Thanks
Narasimha

Feature request: Support of java 21

Hello,

Java 21 will be released in September 2023. We will upgrade our services at this date.
Could the JCE provider be compatible with Java 21 ?

Why Java examples for JCE SDK5 generate KeyPair to encrypt data?

My understanding is, Private Key should never leave HSM cluster. HSM-Client should pass key-handle, Mechanism and payload to the HSM-Server and HSM-Server should encrypt or sign the payload and give it back to the HSM-Client. But the examples in the official documentation generates KeyPair and use actual PrivateKey to encrypt. Please let me know if my understanding is correct and point me to some Java example where encryption and signing happens on HSM-Server and not on HSM-Client

Unit testing options

Hi,
are there any hsm in-memory mocks available that I can use for building out my test suite?

Thanks!
adi

Error while loading key by handle

After updating to 3.1.0, we have an error while loading a key by key handle.

The exception is :

java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Byte;
  at com.cavium.key.CaviumKeyAttributes.getModulus(CaviumKeyAttributes.java:138)
  at com.cavium.key.CaviumRSAPrivateKey.<init>(CaviumRSAPrivateKey.java:48)
  at xxxx.xxxxx.xxxxx.CaviumUtils.getKeyByHandle(CaviumUtils.java:241)

The CaviumUtils.getKeyByHandle is an exact copy of https://github.com/aws-samples/aws-cloudhsm-jce-examples/blob/master/src/main/java/com/amazonaws/cloudhsm/examples/KeyUtilitiesRunner.java#L230

After some investigation, we find something strange in the CaviumKeyAttributes.getModulus method (CaviumKeyAttributes.java:106), specially when we compare it with the CloudHsmKeyAttributesMap.calculateModulus method (CloudHsmKeyAttributesMap.java:118).

While running KeyUtilitiesRunner reported error Communication with the device was lost during the execution of the function

Exception in thread "main" com.amazonaws.cloudhsm.jce.jni.exception.ProviderException: The underlying Provider connection was lost: Communication with the device was lost during the execution of the function.
at com.amazonaws.cloudhsm.jce.jni.CloudHsmObjectFinder.do_find(Native Method)
at com.amazonaws.cloudhsm.jce.jni.CloudHsmObjectFinder.find(CloudHsmObjectFinder.java:10)
at com.amazonaws.cloudhsm.jce.provider.CloudHsmKeyStore.engineGetKey(CloudHsmKeyStore.java:522)
at com.amazonaws.cloudhsm.jce.provider.KeyStoreWithAttributes.getKey(KeyStoreWithAttributes.java:182)
at com.amazonaws.cloudhsm.examples.KeyUtilitiesRunner.getKeyByUsingAttributesMap(KeyUtilitiesRunner.java:222)
at com.amazonaws.cloudhsm.examples.KeyUtilitiesRunner.main(KeyUtilitiesRunner.java:167)

Please help!!

Util.findKey() deprecated

Hi Guys!

Can you please advise why com.cavium.cfm2.Util.findKey() is deprecated?

What should I use instead to get key handle by key label?

Thanks.

AesKey getEncoded() returns null

Some libraries like the popular jjwt for JSON web tokens try to validate the key length to match the requested encryption algorithm (in my case, A256GCM).

This fails however because AesKey#getEncoded() returns null, which the jjwt library treats as 0 bits.

Would it be better if AesKey#getEncoded() threw UnsupportedOperationException, especially if the key is not extractable?

Failing to Sign with Key created in AWS Cloud HSM Token

I am Creating the RSA Keypair in AWS Cloud HSM with the following attribute
KeyAttributesMap publicKeyAttributesMap = new KeyAttributesMap(); KeyAttributesMap privateKeyAttributesMap = new KeyAttributesMap(); privateKeyAttributesMap.put(KeyAttribute.TOKEN, Boolean.TRUE); privateKeyAttributesMap.put(KeyAttribute.SIGN, Boolean.TRUE); publicKeyAttributesMap.put(KeyAttribute.TOKEN, Boolean.TRUE); publicKeyAttributesMap.put(KeyAttribute.VERIFY, Boolean.TRUE);

I can use this private key to create a self signed certificate. But When I am trying to create a CMS Signature I got the following exception
iaik.tsp.TspSigningException: Can't sign TimeStampToken: java.security.NoSuchAlgorithmException: Error computing signature value: iaik.cms.CMSException: Unable to calculate signature: java.security.SignatureException: Cannot calculate RSA siganture: com.amazonaws.cloudhsm.jce.jni.exception.KeyUsageException: An attempt has been made to use a key for a cryptographic purpose that the key's attributes are not set to allow it to do. at iaik.tsp.TimeStampToken.signTimeStampToken(SourceFile:967) at iaik.tsp.TimeStampToken.signTimeStampToken(SourceFile:859) at iaik.tsp.TimeStampToken.signTimeStampToken(SourceFile:1024)

I check the AWS documentation but there is not such attribute that defining private key purpose. No similar question found on AWS.

What causing to stop private key to sign CMS

Problem with AES Wrap/Unwrap

Hi,

I am trying to import an AES key into the HSM using an AES wrapping key generated in the HSM. When i try to call the wrap method i get the following error. Java Security InvalidKeyException: Non CloudHsm key is not supported for this cipher operation. Is wwrapping of an externally generated key (Non Cavium/CloudHSM key) not supported? I tried this on both SDK3 and SDK5 and get similar error. Please find my code snippet attached below.

Cipher cipher = Cipher.getInstance("AESWrap/ECB/NoPadding", CloudHsmProvider.PROVIDER_NAME);
KeyStore keyStore = KeyStore.getInstance(CloudHsmProvider.PROVIDER_NAME);
keyStore.load(null, null);
SecretKey wrapKey = (SecretKey) keyStore.getKey("wrappingkey", null);
cipher.init(Cipher.WRAP_MODE, wrapKey);
SecretKey originalKey = new SecretKeySpec(value, 0, value.length, "AES");
byte[] wrappedAESKey = cipher.wrap(originalKey); //Thows exception here
cipher.init(Cipher.UNWRAP_MODE, wrapKey);
Key key = cipher.unwrap(wrappedAESKey, "AES", Cipher.SECRET_KEY);
return key;

Appreciate any help in this regard.

Thanks
Nara

No way to specify algorithm for generic secret key

Some libraries like the popular jjwt for JSON web tokens assume that, when signing/verifying with HS256 algorithm, that the SecretKey#getAlgorithm() returns HmacSHA256

However, loading a generic secret key from CloudHSM KeyStore returns a SecretKey where getAlgorithm() returns GenericSecret. Is there a way to supply the "intended use" algorithm for the key somehow?

How to sync AWS Cloud HSM keystore file across application on different aws instances?

Requirement:
We have an application running on more than one instance in a cluster that uses key pairs, certificates, and symmetric keys which are preloaded in AWS Cloud HSM.

What is the best way to provide the local keystore file which is created when generating key pairs to all the machines in the cluster?

Keys are created on a different instance which is exclusively used on key management only.

When a new key pair is added, that keypair + certificate needs to be available on all application instances.

Generate keypair with a certificate with store file

keytool -genkeypair -alias alias1  -keystore /home/user/my_cloudhsm/my-cloudhsm.store "CN=alias1.example.com, OU=Research, O=Acme, L=XYZ, ST=CA, C=US" -storetype CLOUDHSM  -storepass password -keyalg rsa -keysize 2048 -sigalg sha512withrsa -validity 360  -dname  -J-classpath '-J/opt/cloudhsm/java/*' -J-Djava.library.path=/opt/cloudhsm/lib

Cloudhsm sdk version 5.9 JCE not support ECDH for generate secret ver 3.4 is support using BouncyCastleProvider

Hi, using KeyAgreement for ECDH is fail for generate secret

• KeyAgreement ecdh = KeyAgreement.getInstance("ECDH", CloudHsmProvider.PROVIDER_NAME);
• KeyAttributesMap params = new KeyAttributesMap();
• params.put(KeyAttribute.SIZE, 256);
• ecdh.init(, params);

SecretKey aesKey = ecdh.generateSecret("AES");

in the code using

Security.addProvider(new BouncyCastleProvider());
AuthProvider provider;
try {
provider = (AuthProvider) Security.getProvider(CloudHsmProvider.PROVIDER_NAME);
if (provider == null) {
provider = new CloudHsmProvider();
}
Security.addProvider(provider);
} catch (IOException | ProviderInitializationException | LoginException ex) {
System.out.println(ex);
return;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.