Java Code Signing
This guide presents a detailed walkthrough for Java Code Signing, underscoring the importance of utilizing signing keys generated on either Luna HSM or Luna Cloud HSM to enhance security and trustworthiness. The integration of Java Code Signing with Luna HSM or Luna Cloud HSM ensures robust security for desktop Java applications and .jar files. The process involves creating a keystore and a Certificate Signing Request (CSR), followed by the installation of the code signing certificate on the keystore. Users can then employ private keys to sign .jar files, embedding the corresponding public key and certificate for subsequent signature verification.
The key benefits of this integration are:
-
Secure generation, storage, and protection of the identity signing private keys using either FIPS 140-2 or FIPS 140-3 Level 3 validated hardware.
-
Full life cycle management of the keys to ensure their integrity and reliability throughout their usage.
-
Maintenance of a comprehensive HSM audit trail for transparency and accountability in key operations. It's important to note that Luna Cloud HSM service does not have access to this secure audit trail.
-
Significant performance enhancements by offloading cryptographic operations from application servers.
Supported platforms
This integration has been tested and verified on Windows and Linux platforms.
Prerequisites
The prerequisites for this integration are:
Set up Luna HSM
As the first step to accomplish this integration, you need to set up either On-Premise Luna HSM or Luna Cloud HSM.
Set up On-Premise Luna HSM
Follow these steps to set up your on-premise Luna HSM:
Verify that the HSM is set up, initialized, provisioned, and ready for deployment.
This integration has been verified on the RHEL platform.
Refer to Luna HSM documentation for detailed steps on creating NTLS connection, initializing the partitions, and assigning various user roles.
Create a partition on the HSM that will be later used by Java Code Signing. If you are using a Luna Network HSM, register a client for the system and assign the client to the partition to create an NTLS connection. Initialize the Crypto Officer and Crypto User roles for the registered partition.
Run the following command to verify that the partition has been successfully registered and configured:
/usr/safenet/lunaclient/bin/lunacm
You should see the following output:
lunacm (64-bit) v10.2.0-111. Copyright (c) 2020 SafeNet. All rights reserved. Available HSMs: Slot Id -> 0 Label -> JCS Serial Number -> 1280780175877 Model -> LunaSA 7.3.0 Firmware Version -> 7.3.0 Configuration -> Luna User Partition With SO (PW) Key Export With Cloning Mode Slot Description -> Net Token Slot FM HW Status -> FM Ready Current Slot Id: 0
Refer to Luna HSM documentation for detailed steps on creating NTLS connection, initializing the partitions, and assigning various user roles.
Manage User Access to Your HSM
Initially, only the root user can access the Hardware Security Module (HSM). However, you can grant access to specific non-root users by including them in the hsmusers
group. This group is automatically created when you install the client software. Even if you later uninstall the client software, the hsmusers
group remains intact, ensuring you can upgrade your software without losing your user access settings.
Add users to the hsmusers group
If you wish to permit non-root users or applications to interact with the HSM device, you must assign these users to the hsmusers group. Make sure that the users you intend to add to the hsmusers group are already established on the client workstation. Only users added to the hsmusers group will be granted access to the HSM device. Follow these steps to add a user to the hsmusers group:
Ensure that you possess sudo privileges on the client workstation.
Add a user to the hsmusers group using the command:
sudo gpasswd --add [username] hsmusers
Replace username
with the actual username you want to include in the hsmusers group.
Remove users from the hsmusers group
If you need to withdraw a user's authorization to access the HSM device, you can remove them from the hsmusers group. Carry out the following steps to remove a user from the hsmusers group:
Confirm that you hold sudo privileges on the client workstation.
Eliminate a user from the hsmusers group using the command:
sudo gpasswd --add [username] hsmusers
Replace username
with the specific username you want to exclude from the hsmusers group. To observe the changes, you will need to log in again.
Any user you remove will retain access to the HSM device until the client workstation is rebooted.
Set up Luna HSM High-Availability Group
Refer to Luna HSM documentation for HA steps and details regarding configuring and setting up two or more HSM boxes on host systems. You must enable the HAOnly setting in HA for failover to work so that if the primary goes down due to any reason, all calls get automatically routed to the secondary until the primary recovers and starts up.
Set up Luna Cloud HSM
Follow these steps to set up your Luna Cloud HSM:
Transfer the downloaded .zip file to your client workstation using pscp, scp, or other secure means
This integration has been certified on the RHEL platform.
Extract the .zip file into a directory on your client workstation.
Extract or untar the appropriate client package for your operating system. Do not extract to a new subdirectory; place the files in the client install directory.
tar -xvf cvclient-min.tar
Run the setenv script to create a new configuration file containing information required by the Luna Cloud HSM service.
source ./setenv
To add the configuration to an already installed UC client, use the –addcloudhsm option when running the setenv script.
Run the LunaCM utility and verify the Cloud HSM service is listed.
If your organization requires non-FIPS algorithms for your operations, ensure that the Allow non-FIPS approved algorithms check box is checked. For more information, refer to Supported Mechanisms.
Install JDK
Install the Java Development Kit (JDK) on your server or local computer to ensure that the keytool command is available for running the instructions provided here.
Sign and verify JAR files
The steps involved in signing JAR files using keys generated on a Luna HSM are as follows:
Configure Java for Luna Keystore
Generate signing key and certificate on Luna Keystore
Validate the presence of the private key within the Luna HSM
Generate certificate request for Luna Keystore signing key
Import CA's root certificate and signed certificate
Configure Java for Luna Keystore
To ensure your Java environment is properly configured for the Luna Keystore, please follow these steps:
These steps are only valid for JDK 7 and JDK 8. If you are using JDK 11 or JDK 21, you can skip this section.
Open the Java Security Configuration file java.security
located in [JDK_installation_directory]/jre/lib/security
.
Edit the file and add the Luna Provider as follows:
security.provider.1=sun.security.provider.Sun security.provider.2=com.safenetinc.luna.provider.LunaProvider security.provider.3=sun.security.rsa.SunRsaSign security.provider.4=sun.security.ec.SunEC security.provider.5=com.sun.net.ssl.internal.ssl.Provider security.provider.6=com.sun.crypto.provider.SunJCE security.provider.7=sun.security.jgss.SunProvider security.provider.8=com.sun.security.sasl.Provider security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI security.provider.10=sun.security.smartcardio.SunPCSC
Save the changes to the java.security
file.
Create HSM keystore
Follow these steps to establish an HSM keystore:
Copy necessary files:
-
On Windows, copy
LunaAPI.dll
andLunaProvider.jar
from[Luna_installation_directory]/jsp/lib
to[JDK_installation_directory]/jre/lib/ext
. -
On UNIX, copy
libLunaAPI.so
andLunaProvider.jar
from the same directory to[JDK_installation_directory]/jre/lib/ext
.
Skip this step for JDK 11/21.
Set the environment variables for JAVA_HOME
and PATH
:
export JAVA_HOME=[JDK_installation_directory] export PATH=$JAVA_HOME/bin:$PATH
For Windows, add the JDK bin folder to the PATH variable under System Environments.
Create configuration file:
-
Create a file named
lunastore
(or any user-defined name) in the current working directory. -
Add the following entry, replacing
[partition_label]
with your Luna HSM partition name.
tokenlabel:[partition_label]
- Save the file.
Generate signing key and certificate on Luna Keystore
For JDK 7/8
keytool -genkeypair -alias lunakey -keyalg RSA -sigalg SHA256withRSA -keypass userpin1 -keysize 2048 -keystore lunastore -storepass userpin1 -storetype luna
For JDK 11/21
keytool -genkeypair -alias lunakey -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keypass userpin1 -keystore lunastore -storetype Luna -storepass userpin1 -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Upon executing the command, the system prompts for various details, including first and last name, organizational unit, organization, city or locality, state or province, and country code. Confirm the correctness of the provided information, and a new key pair will be generated on the Luna HSM.
The provided command uses userpin1
as the storepass, representing the partition Crypto Officer pin set during the initialization of the CO role for the partition.
Validate the presence of the private key within the Luna HSM
To validate the presence of the private key within the Luna HSM:
Execute the following command:
For JDK 7/8
keytool -list -v -storetype luna -keystore lunastore
For JDK 11/21
keytool -list -v -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Enter the keystore password when prompted. The resulting output provides extensive information regarding the stored private key, including:
-
Alias name
-
Creation date
-
Entry type
-
Certificate chain length
-
Certificate details (issuer, serial number, validity period, fingerprints, etc.)
Ensure that the private key is listed, confirming its successful presence within the Luna HSM.
Generate certificate request for Luna Keystore signing key
To generate certificate request for Luna KEystore signing key:
Execute the following command:
For JDK 7/8
keytool -certreq -alias lunakey -sigalg SHA256withRSA -file certreq_file -storetype luna -keystore lunastore
For JDK 11/21
keytool -certreq -alias lunakey -sigalg SHA256withRSA -file certreq_file -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Enter the keystore password when prompted. The file certreq_file
will be generated in the current directory.
Submit CSR to CA
Submit the Certificate Signing Request (CSR) file (certreq_file
) to your Certification Authority (CA). Ensure that the CA authenticates the request using the Code Signing template. Retrieve the signed certificate or a certificate chain from the CA.
Import CA root certificate and signed certificate
Import CA root certificate and signed certificate or certificate chain into keystore.
For JDK 7/8
- Import CA root certificate:
keytool -trustcacerts -importcert -alias rootca -file root.cer -keystore lunastore -storetype luna
- Import signed certificate or certificate chain:
keytool -importcert -trustcacerts -alias lunakey -file signing.p7b -keystore lunastore -storetype luna
For JDK 11/21
- Import CA root certificate.
keytool -trustcacerts -importcert -alias rootca -file root.cer -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
- Import signed certificate or certificate chain:
keytool -trustcacerts -importcert -alias lunakey -file signing.p7b -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Here, root.cer
and signing.p7b
represent the CA root certificate and signed certificate chain, respectively.
Verify keystore contents
To verify keystore contents in Luna HSM:
Execute the following command:
For JDK 7/8
keytool -list -v -storetype luna -keystore lunastore
For JDK 11/21
keytool -list -v -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Enter the keystore password when prompted. The output provides extensive information about the keystore contents, including:
-
Alias name
-
Creation date
-
Entry type
-
Certificate chain length
-
Certificate details for each entry (issuer, serial number, validity period, fingerprints, etc.)
Sign and verify JAR files
To sign and verify JAR files using the Luna HSM, follow these steps:
Move the JAR file into the current working directory.
Sign the JAR file using the jarsigner utility.
For JDK 7/8
jarsigner -keystore lunastore -storetype luna -signedjar [name_of_signed_jar_to_be_generated] [jar_to_be_signed] [alias_of_private_key] -tsa [time_stamping_authority_url]
For JDK 11/21
jarsigner -keystore lunastore -storetype luna -signedjar [name_of_signed_jar_to_be_generated] [jar_to_be_signed] [alias_of_private_key] -tsa [time_stamping_authority_url] -providername LunaProvider -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=[luna_JSP_lib_path] -J-cp -J[luna_provider_jar_file]
Enter the passphrase for the keystore when prompted. The JAR will be signed, and certificate details will be displayed.
Verify the signed JAR file to ensure the file hasn't been tampered with and comes from a trusted source:
jarsigner -verify signedsample.jar -verbose –certs
The output provides a comprehensive overview of the JAR file, including:
-
s
: Indicates the successful verification of the signature. -
m
: Denotes the file's presence in the manifest, which contains metadata about JAR contents. -
k
: Verifies the existence of at least one certificate in the secure keystore. -
X
: Highlights entries not signed by the specified alias, a unique identifier.
Additionally, detailed information about the signer, used algorithms, and timestamp is displayed, such as:
-
Signed by
: CN=Administrator, CN=Users, DC=intgca, DC=com -
Digest algorithm
: SHA-256 -
Signature algorithm
: SHA256withRSA, 2048-bit key -
Timestamped by
: CN=GlobalSign TSA for Standard - G2, O=GMO GlobalSign Pte Ltd, C=SG" on Wed Aug 26 17:43:16 UTC 2020 -
Timestamp digest algorithm
: SHA-256 -
Timestamp signature algorithm
: SHA1withRSA, 2048-bit key
The conclusive jar verified
message at the end confirms the legitimacy of the JAR file and provides information about the expiration dates of the signer certificate and timestamp. This successful signing and verification, coupled with the secure storage of the private key and signing certificate on the Luna HSM, marks the seamless completion of the Java Code Signing integration with Luna HSM.
Migrate JKS keystore
To seamlessly migrate a JKS keystore to the Luna HSM, follow these steps:
Ensure that JAVA_HOME and PATH environment variables are appropriately configured.
Configure Luna HSM partition.
Configure Java for Luna Keystore.
Migrate JKS keystore to Luna HSM.
For JDK 7/8
keytool -importkeystore -srckeystore keystore.jks -destkeystore lunastore -srcstoretype jks -deststoretype luna
For JDK 11/21
keytool -importkeystore -srckeystore keystore.jks -destkeystore lunastore -srcstoretype jks -deststoretype luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
When prompted:
-
Enter the destination keystore password.
-
Enter the source keystore password.
-
If an existing entry alias is detected, choose to overwrite or not.
Verify Keystore contents in Luna HSM.
For JDK 7/8
keytool -list -v -storetype luna -keystore lunastore
For JDK 11/21
keytool -list -v -keystore lunastore -storetype Luna -providerpath "/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar" -providerclass com.safenetinc.luna.provider.LunaProvider -J-Djava.library.path=/usr/safenet/lunaclient/jsp/lib/ -J-cp -J/usr/safenet/lunaclient/jsp/lib/LunaProvider.jar
Enter the keystore password when prompted.
Verify successful migration.
You can now sign and verify JAR files using the migrated signing keys on the Luna HSM.