Using Java Keytool with 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
>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]: Thales 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=Thales, 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]: Thales 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=Thales, 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-mikeca -file mike_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-mikeca Creation date: Oct 4, 2012 Entry type: trustedCertEntry Owner: EMAILADDRESS=username@thales.com, CN=mike CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT Issuer: EMAILADDRESS=username@thales.com, CN=mike 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-mikeca.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-mikeca
Creation date: Oct 4, 2012
Entry type: trustedCertEntry Owner: EMAILADDRESS=username@thales.com, CN=mike CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Issuer: EMAILADDRESS=username@thales.com, CN=mike 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=username@thales.com, CN=mike 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=username@thales.com, CN=mike CA, OU=SE, O=SFNT, L=bgy, ST=bg, C=IT
Issuer: EMAILADDRESS=username@thales.com, CN=mike 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-mikeca -file /home/mike/luna-keystores/mike_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 mike_CA.p7b -out mike_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 mike_CA.crt