Using Java Keytool with SafeNet Luna PCIe HSM

This page describes how to use the Java KeyTool application with the LunaProvider.

Limitations

The following limitations apply:

>You cannot use the importkeystore command to migrate keys from a Luna KeyStore to another KeyStore.

>Private keys cannot be extracted from the KeyStore unless you have the Key Export model of the HSM.

>By default secret keys created with the LunaProvider are non-extractable.

The example below uses a KeyStore file containing only the line “slot:0”. This tells the Luna KeyStore to use the token in slot 0.

NOTE   The Luna Keystore is not a physical file like a regular JKS. It is a virtual interface to the HSM and contains only handles for the private key objects.

For information on creating keys through Key Generator or Key Factory classes please see the LunaProvider Javadoc or the JCA/JCE API documentation.

Keys (with self signed certificates) can be generated using the keytool by specifying a valid Luna KeyStore file and specifying the KeyStore type as “Luna”. The password presented to authenticate to the KeyStore is the challenge password of the partition.

Example
keytool –genkeypair –alias myKey –keyalg RSA –sigalg SHA256withRSA –keystore keystore.luna –storetype Luna
Enter keystore password:
What is your first and last name?
[Unknown]:  test
What is the name of your organizational unit?
[Unknown]:  codesigning
What is the name of your organization?
[Unknown]:  SafeNet Inc
What is the name of your City or Locality?
[Unknown]:  Ottawa
What is the name of your State or Province?
[Unknown]:  ON
What is the two-letter country code for this unit?
[Unknown]:  CA
Is CN=test, OU=codesigning, O=SafeNet Inc, L=Ottawa, ST=ON, C=CA correct?
[no]:  yes
Enter key password for <myKey>
(RETURN if same as keystore password):

Keytool Usage and Examples

The LunaProvider is unable to determine which PKCS#11 slot to use without providing a keystore file. This file can be manually created to specify the desired slot by either the slot number or partition label. The naming of the files is not important - only the contents.

The keytool examples below refer to a keystore file named bylabel.keystore. Its content is just one line:

tokenlabel:a-partition-name

where a-partition-name is the name of the partition you want the Java client to use.

Here is the (one line) content of a keystore file that specifies the partition by slot number:

slot:0

where 1 is the slot number of the partition you want the Java client to use.

To test that the Java configuration is correct, execute:

my-lunaclient:~/luna-keystores$ keytool -list -v -storetype Luna -keystore bylabel.keystore  

The system requests the password of the partition and shows its contents.

Here is a sample command to create an RSA 2048 bit key with SHA256withRSA self-signed certificate. This example uses java 6, other versions might be slightly different.

keytool -genkeypair -alias keyLabel -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -storetype Luna -keystore bylabel.keystore -validity 365

Enter keystore password:
What is your first and last name?
  [Unknown]:  mike
What is the name of your organizational unit?
  [Unknown]:  appseng
What is the name of your organization?
  [Unknown]:  safenet
What is the name of your City or Locality?
  [Unknown]:  ottawa
What is the name of your State or Province?
  [Unknown]:  on
What is the two-letter country code for this unit?
  [Unknown]:  ca
Is CN=mike, OU=appseng, O=safenet, L=ottawa, ST=on, C=ca correct?
  [no]:  yes
Enter key password for <keyLabel>
  (RETURN if same as keystore password):

With the Luna provider there is no concept of a key password and anything entered is ignored.

The following is a more elaborate sequence of keytool usage where the final goal is to have the private key generated in the HSM through keytool “linked” to its certificate.

Import CA certificate

It is mandatory to import the CA certificate – keytool verifies the chain before importing a client certificate:

my-lunaclient:~/luna-keystores$ keytool -importcert -storetype Luna -keystore bylabel.keystore -alias root-ugoca -file Ugo_CA.crt

It is not required to import this certificate in the Java default cacerts keystore.   

Generate private key

Generate the private key. It is not important that the sigalg specified matches the one used by the CA. You can also have OU, O, L, ST, and C different from the ones in the CA certificate.

my-lunaclient:~/luna-keystores$ keytool -genkeypair -alias java-client2-key -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -storetype Luna -keystore bylabel.keystore
Enter keystore password:
What is your first and last name?
[Unknown]:  java-client2
What is the name of your organizational unit?
[Unknown]:  SE
What is the name of your organization?
[Unknown]:  SFNT
What is the name of your City or Locality?
[Unknown]:  bgy
What is the name of your State or Province?
[Unknown]:  bg
What is the two-letter country code for this unit?
[Unknown]:  IT
Is CN=java-client2, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT correct?
[no]:  yes
Enter key password for <java-client2-key>
(RETURN if same as keystore password):

Verify that the private key is in the partition:

my-lunaclient:~/luna-keystores$ keytool -list -v -storetype Luna -keystore bylabel.keystore
Enter keystore password:
Keystore type: LUNA
Keystore provider: LunaProvider
Your keystore contains 2 entries
Alias name: root-ugoca
Creation date: Oct 4, 2012
Entry type: trustedCertEntry
Owner: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Issuer: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Serial number: 1
Valid from: Thu Oct 04 09:02:00 CEST 2012 until: Tue Oct 04 09:02:00 CEST 2022
Certificate fingerprints:
      MD5:  A2:15:4F:94:70:2B:D2:F7:C0:96:B1:47:F2:1D:03:E9
      SHA1: B3:4A:68:0A:8D:12:39:86:11:CE:EF:22:1B:D1:DE:8D:E9:19:2B:F4
      Signature algorithm name: SHA256withRSA
      Version: 3
*******************************************
*******************************************
Alias name: java-client2-key
Creation date: Oct 4, 2012
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=java-client2, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Issuer: CN=java-client2, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Serial number: 506d42dd
Valid from: Thu Oct 04 10:03:41 CEST 2012 until: Wed Jan 02 09:03:41 CET 2013
Certificate fingerprints:
      MD5:  7A:37:72:6B:8A:05:B6:49:91:70:0F:C4:04:1F:69:D9
      SHA1: 05:CD:9F:A5:37:0B:A6:A3:65:24:56:40:5E:29:2D:95:2D:53:8F:5F
      Signature algorithm name: SHA256withRSA
      Version: 3  

Create the CSR

Create the CSR to be submitted to the CA.

my-lunaclient:~/luna-keystores$ keytool -certreq -alias java-client2-key -file client2-ugoca.csr -storetype Luna -keystore bylabel.keystore
Enter keystore password:

Now have the CSR signed by the CA. Have the issued certificate exported to include the certificate chain. Without the chain, keytool fails with the error:

java.lang.Exception: Failed to establish chain from reply

If you do not have the chain, you can use the steps in the section below to build the chain yourself.

To translate a PKCS#7 exported certificate from DER format to PEM format use the following:

my-lunaclient $ openssl pkcs7 -inform der -in Luna_Key.p7b -outform pem -out Luna_Key-pem.p7b

Microsoft CA exports certificates with chain only in PKCS#7 PEM encoded format.

Import client certificate

Now import the client certificate:

user@myserver:~/luna-keystores$ keytool -importcert -storetype Luna -keystore bylabel.keystore -alias java-client2-key -file java-client2.crt
Enter keystore password:
Certificate reply was installed in keystore   

Ensure that it is linked to the private key generated previously – the chain length is not 1 (Certificate chain length: 2)

user@myserver:~/luna-keystores$ keytool -list -v -storetype Luna -keystore bylabel.keystore   
Enter keystore password: Keystore type: LUNA   
Keystore provider: LunaProvider Your keystore contains 2 entries Alias name: root-ugoca  
Creation date: Oct 4, 2012   
Entry type: trustedCertEntry Owner: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Issuer: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Serial number: 1   
Valid from: Thu Oct 04 09:02:00 CEST 2012 until: Tue Oct 04 09:02:00 CEST 2022   
Certificate fingerprints:   
     MD5: A2:15:4F:94:70:2B:D2:F7:C0:96:B1:47:F2:1D:03:E9   
     SHA1: B3:4A:68:0A:8D:12:39:86:11:CE:EF:22:1B:D1:DE:8D:E9:19:2B:F4   
     Signature algorithm name: SHA256withRSA   
     Version: 3 *******************************************   
*******************************************    Alias name: java-client2-key   
Creation date: Oct 4, 2012   
Entry type: PrivateKeyEntry   
Certificate chain length: 2   
Certificate[1]:   
Owner: CN=java-client2, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Issuer: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Serial number: 5   
Valid from: Thu Oct 04 10:07:00 CEST 2012 until: Fri Oct 04 10:07:00 CEST 2013   
Certificate fingerprints:   
      MD5: 4B:F0:9E:BC:EB:6A:88:2B:87:3A:76:35:7C:DE:4B:B4   
      SHA1: F1:0C:BC:E3:A1:97:E4:8B:24:2D:44:43:7A:EA:71:52:B3:C3:20:D7   
      Signature algorithm name: SHA256withRSA   
      Version: 3   
Certificate[2]:   
Owner: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Issuer: EMAILADDRESS=ugo@computer.org, CN=Ugo CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT   
Serial number: 1   
Valid from: Thu Oct 04 09:02:00 CEST 2012 until: Tue Oct 04 09:02:00 CEST 2022   
Certificate fingerprints:   
      MD5: A2:15:4F:94:70:2B:D2:F7:C0:96:B1:47:F2:1D:03:E9   
      SHA1: B3:4A:68:0A:8D:12:39:86:11:CE:EF:22:1B:D1:DE:8D:E9:19:2B:F4   
      Signature algorithm name: SHA256withRSA   
      Version: 3   

How to build a certificate with chain ...

When you receive the client certificate without the chain, it is possible to build a PKCS#7 certificate that includes the chain (and then feed it to keytool -importcert). In short, the “single” certificates without the chain can be “stacked” together by manually editing a PEM cert file; this PEM cert file can then be translated into a PKCS#7 cert. How? Like this:  

1.Prerequisites. Have all the certs in .crt format. The cert in this format is represented as an ASCII file starting with the line

-----BEGIN CERTIFICATE-----

and ending with

-----END CERTIFICATE----- 

For example, if the client cert is issued by a subCA and the subCA is signed by a root CA, you will have 3 cert files – the client cert, the subCA cert, and the root CA cert. If the certs are not in .crt format, openssl can be used to transform the format that you have into .crt format. See notes below.   

2.Open a new text file, calling it, for example, cert-with-chain.crt. Insert into this file the content of the certificates in the chains. For the above example, you must first insert the client cert, then the subCA cert, then the root CA cert. The content of the file would then resemble the following:

-----BEGIN CERTIFICATE-----  
             <-- client cert goes here 
-----END CERTIFICATE----- 
-----BEGIN CERTIFICATE----- 
             <-- subCA cert goes here 
-----END CERTIFICATE----- 
-----BEGIN CERTIFICATE-----
             <-- root CA cert goes here
-----END CERTIFICATE-----  

3.Use the following openssl command to convert the new certificate with chain, that you just created above, to a PKCS#7 certificate with chain:

my-sa $ openssl crl2pkcs7 -nocrl -certfile HSM_Luna-manual-chain.crt -out HSM_Luna-manual-chain.p7b -certfile root_CA.crt  

4.Keytool is then able to import this .p7b certificate into the Luna keystore and correctly validate the chain.

Additional minor notes

1.Command to add a CA to the default CA cert store “cacerts”:

root@myserver:~# keytool -importcert -trustcacerts -alias root-ugoca -file /home/ugo/luna-keystores/Ugo_CA.crt -keystore /etc/java-6-sun/security/cacerts  

2.Use the following openssl command to convert a PKCS#7 certificate DER-encoded into a PKCS#7 PEM-encoded certificate:

user@myserver:~/tmp/$ openssl pkcs7 -inform der -in java-client2.p7b -out java-client2-pem.p7b  

3.Use the following openssl command to convert a PKCS#7 DER-encoded certificate into a .crt PEM certificate:

user@myserver:~/tmp/$ openssl pkcs7 -print_certs -inform der -in Ugo_CA.p7b -out Ugo_CA-p7-2-crt.crt  

4.Use the following openssl command to convert a PEM certificate with chain to a PKCS#7 with chain:

user@myserver:~/tmp/$ openssl crl2pkcs7 -nocrl -certfile HSM_Luna-manual-chain.crt -out HSM_Luna-manual-chain.p7b -certfile Ugo_CA.crt