Skip to main content

Code Signing (JAR) with Primus HSM

This guide covers two end-to-end workflows for signing Java Archives (JARs) with private keys stored on a Securosys Primus HSM:

  1. Self-signed certificate chain - Root CA → Intermediate CA → Code Signing, fully managed on the HSM.
  2. CA-issued certificate - Code-signing key on the HSM, certificate issued by an external CA (DigiCert, SwissSign, etc.).
HSM connection placeholder

All examples use <HSM> as shorthand.

-host <host> -port <port> -user <user> -password <password> -proxyuser <proxyuser> -proxypassword <proxypassword>

Note: When using Securosys CloudHSM with JarsignerX or KeytoolX, proxy credentials are required. In this case, use the parameters -proxyuser and -proxypassword.

Please note that these parameters differ from the standard Primus tools usage, which uses

-primusproxyuser and -primusproxypassword.


Workflow 1: Self-Signed Certificate Chain

Use this workflow for internal distribution, testing, or when you manage your own PKI.

Create the Root CA

# Generate RSA 4096-bit key pair
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-genkeypair -alias root-ca-key \
-keyalg RSA -keysize 4096 -sigalg SHA256withRSA \
-dname "CN=My Root CA,OU=IT,O=My Organisation,C=CH" \
-keysize 4096 \
-validity 3650

# Re-issue self-signed cert with CA extensions (BasicConstraints)
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-selfcert -alias root-ca-key \
-sigalg SHA256withRSA \
-dname "CN=My Root CA,OU=IT,O=My Organisation,C=CH" \
-validity 3650 \
-ext bc=ca:true -ext ku=keyCertSign,cRLSign

# Export root certificate
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-exportcert -alias root-ca-key -rfc -file root-ca.pem

Create the Intermediate CA

# Generate key pair
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-genkeypair -alias intermediate-ca-key \
-keyalg RSA -keysize 4096 -sigalg SHA256withRSA \
-dname "CN=My Intermediate CA,OU=IT,O=My Organisation,C=CH" \
-keysize 4096 \
-validity 1825

# Generate CSR
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-certreq -alias intermediate-ca-key \
-sigalg SHA256withRSA -file intermediate-ca.csr

# Root CA signs the intermediate certificate
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-gencert -alias root-ca-key \
-infile intermediate-ca.csr -outfile intermediate-ca.pem \
-validity 1825 \
-ext bc=ca:true -ext ku=keyCertSign,cRLSign -rfc

Create the Code-Signing Key

# Generate RSA 4096-bit key pair
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-genkeypair -alias codesign-key \
-keyalg RSA -keysize 4096 -sigalg SHA256withRSA \
-dname "CN=My Code Signing,OU=IT,O=My Organisation,C=CH" \
-keysize 4096 \
-validity 730

# Generate CSR
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-certreq -alias codesign-key \
-sigalg SHA256withRSA -file codesign.csr

# Intermediate CA signs the code-signing certificate
java -jar primus-tools.jar KeytoolX \
<HSM> \
-storetype Primus \
-gencert -alias intermediate-ca-key \
-infile codesign.csr -outfile codesign.pem \
-validity 730 \
-ext eku=codeSigning -ext ku=digitalSignature -rfc

Assemble the Chain

cat codesign.pem intermediate-ca.pem root-ca.pem > codesign-fullchain.pem

The file should contain three certificates in order: end-entity → intermediate → root.

Continue now with Workflow 3 - Sign & Verify.


Workflow 2: CA-Issued Certificate

Use this workflow for public distribution where JARs must be signed with a certificate trusted by end users (e.g. DigiCert, SwissSign, GlobalSign).

Create Key and Generate CSR

java -jar primus-tools.jar KeytoolX <HSM> -storetype Primus \
-genkeypair -alias codesign-key \
-keyalg RSA -keysize 4096 -sigalg SHA256withRSA \
-dname "CN=My Code Signing,OU=IT,O=My Organisation,C=CH" \
-validity 730

java -jar primus-tools.jar KeytoolX <HSM> -storetype Primus \
-certreq -alias codesign-key \
-sigalg SHA256withRSA -file codesign.csr

Submit CSR to Your CA

  1. Submit codesign.csr to your CA's code-signing certificate portal.
  2. Complete the CA's validation process.
  3. Download the signed certificate and full chain as a PEM file (name it: codesign-fullchain.pem).

The chain PEM should contain certificates in order: end-entity → intermediate(s) → root.

Workflow 3: Sign & Verify

Sign

java \
--add-opens=java.base/javax.security.auth.x500=ALL-UNNAMED \
--add-opens=java.base/sun.security.x509=ALL-UNNAMED \
-jar primus-tools.jar JarsignerX \
<HSM> \
-storetype Primus -providerName SecurosysPrimusXSeries \
-tsa http://tsa.swisssign.net \
-tsa http://timestamp.digicert.com \
-digestalg SHA-256 \
-certchain codesign-fullchain.pem \
myapp.jar codesign-key
ParameterDescription
tsaThe timestamp authority
myapp.jarthe jar to be signed
codesign-keythe HSM KeyName

Verify

Online (via HSM):


java -jar primus-tools.jar JarsignerX <HSM> -verify myapp.jar

Offline (no HSM needed):

keytool -importcert -alias root-ca-key -file codesign-fullchain.pem -keystore truststore.jks -storepass changeit -noprompt
keytool -importcert -alias intermediate-ca-key -file intermediate-ca.pem -keystore truststore.jks -storepass changeit -noprompt
keytool -importcert -alias codesign-key -file codesign.pem -keystore truststore.jks -storepass changeit -noprompt
jarsigner -verify -keystore truststore.jks -storepass changeit myapp.jar

CA-issued certificates are trusted by default; standard jarsigner works:

jarsigner -verify myapp.jar

Known Issues

  • KeytoolX -importcert corrupts Private Key Entry, read this for details
Get started withCloudHSM for free.
Other questions?Ask Sales.
Feedback
Need help?