Java Integration
sslTrus provides the sslTrusJarsigner Java Provider, which can be used with the jarsigner tool included in the JDK to sign Java JAR files through a remote code signing service.
During the signing process, the code signing private key is always stored in the cloud HSM. The local side is responsible for generating the data to be signed and the signature structure, and calls the remote service through the sslTrusJarsigner Provider to complete the private key signing.
In addition to JAR signing, sslTrusJarsigner also provides XMLDSig signing capabilities for XML digital signature scenarios.
Preparation
Before use, please prepare:
- JDK 8 or higher.
sslTrusJarsigner-<version>.jar.- Access Key.
- Access Secret.
- Certificate code (Cert Code).
- The JAR file or XML file to be signed.
The <version>, access credentials, certificate code, and file paths in the examples in this article need to be replaced with actual values.
Download sslTrusJarsigner
Download the latest release package from the sslTrusJarsigner release page and extract it.
The release package includes:
sslTrusJarsigner-<version>.jar
SHA-256 校验文件
It is recommended to verify the integrity of sslTrusJarsigner-<version>.jar using SHA-256 checksum files before use.
Check the runtime environment
First, confirm that Java and the JDK built-in jarsigner can be used properly:
java -version
jarsigner -help
Check the sslTrusJarsigner version:
java -jar sslTrusJarsigner-<version>.jar --version
View help:
java -jar sslTrusJarsigner-<version>.jar --help
If the jarsigner command does not exist, confirm that a complete JDK is currently installed, rather than a runtime environment containing only the Java Runtime.
Configure access credentials
sslTrusJarsigner reads the access credentials and certificate ID of the remote code signing service through environment variables.
Linux and macOS
export SSLTRUS_JARSIGNER_ACCESS_KEY="YOUR_ACCESS_KEY"
export SSLTRUS_JARSIGNER_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SSLTRUS_JARSIGNER_CERT_CODE="YOUR_CERT_CODE"
Windows PowerShell
$env:SSLTRUS_JARSIGNER_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SSLTRUS_JARSIGNER_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SSLTRUS_JARSIGNER_CERT_CODE = "YOUR_CERT_CODE"
If the service personnel provided a dedicated service address, you also need to set SSLTRUS_JARSIGNER_URL.
Linux and macOS:
export SSLTRUS_JARSIGNER_URL="YOUR_SERVICE_URL"
Windows PowerShell:
$env:SSLTRUS_JARSIGNER_URL = "YOUR_SERVICE_URL"
If no dedicated service address is provided, you do not need to set this variable.
Access Secret is a sensitive credential and should not be written into source code, public configuration files, or build logs. In automated environments, it is recommended to inject it through CI/CD Secrets or other credential management mechanisms.
JAR Signing
sslTrusJarsigner integrates with the standard jarsigner tool through the Java Security Provider mechanism.
The following example will:
app-unsigned.jar
Signed output is:
app-signed.jar
JDK 9 or Later
Linux and macOS:
jarsigner \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerPath "sslTrusJarsigner-<version>.jar" \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"
Windows PowerShell:
jarsigner `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerPath "sslTrusJarsigner-<version>.jar" `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"
JDK 8
JDK 8 loads providers differently from JDK 9 and later versions.
First, confirm:
JAVA_HOME
Points to the complete JDK 8 installation directory.
Linux and macOS:
jarsigner \
-J-cp \
-J"$JAVA_HOME/lib/tools.jar:sslTrusJarsigner-<version>.jar" \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"
Windows PowerShell:
jarsigner `
-J-cp `
"-J$env:JAVA_HOME\lib\tools.jar;sslTrusJarsigner-<version>.jar" `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"
When using this, note the following:
- The certificate number at the end of the command must match
SSLTRUS_JARSIGNER_CERT_CODE. - It is recommended to use
-signedjarto output to a new file and avoid overwriting the original JAR. - The example uses
SHA256withRSAto complete code signing. - If a timestamp is not needed, you can remove
-tsaand the timestamp address that follows it.
Timestamp
It is recommended to add a trusted timestamp when signing JAR files for official release.
Used in the example:
http://timestamp.sectigo.com
Corresponding parameters:
-tsa http://timestamp.sectigo.com
The timestamp is used to prove when the signature occurred, and the original JAR file is not uploaded to the timestamp server.
If you need to use another timestamp service, you can replace the address after -tsa with a TSA address that complies with the actual signing policy.
For information on different timestamp services and production environment selection, see References.
XML Signing
sslTrusJarsigner also provides XML digital signing capabilities.
XML files can be signed with the sign-xml command to generate an XMLDSig Enveloped Signature.
During signing, the digest and signature structure required for XMLDSig are generated locally, while the actual RSA private key signing is performed by the remote code signing service.
Linux and macOS
java -jar sslTrusJarsigner-<version>.jar \
sign-xml \
"input.xml" \
"signed.xml" \
"$SSLTRUS_JARSIGNER_CERT_CODE"
Windows PowerShell
java -jar sslTrusJarsigner-<version>.jar `
sign-xml `
"input.xml" `
"signed.xml" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"
The default output KeyInfo includes only the leaf certificate. If the recipient requires the XML to contain the complete certificate chain, add the --full-chain parameter at the end of the command.
After execution completes:
input.xml
For the original XML file,
signed.xml
For output files containing XML digital signatures.
The code signing private key is not written to the XML file, nor is it saved to the local computer.
Generate verification file
After signing is complete, you can generate a JKS file used to verify the signature.
Linux and macOS:
java -jar sslTrusJarsigner-<version>.jar \
generate-keystore \
"$SSLTRUS_JARSIGNER_CERT_CODE" \
"verify.jks" \
"SSLTRUS"
Windows PowerShell:
java -jar sslTrusJarsigner-<version>.jar `
generate-keystore `
"$env:SSLTRUS_JARSIGNER_CERT_CODE" `
"verify.jks" `
"SSLTRUS"
Generate:
verify.jks
This file is only used for signature verification and cannot be used to perform code signing.
The code signing private key remains stored in the remote HSM and will not be written to verify.jks.
Verify JAR signature
Use the generated verify.jks to verify the signature:
jarsigner \
-verify \
-verbose \
-certs \
-keystore "verify.jks" \
-storetype JKS \
-storepass "SSLTRUS" \
"app-signed.jar"
If you only need to view the existing signature information in a JAR, you can execute:
jarsigner -verify -verbose -certs "app-signed.jar"
Signature verification only checks the existing signature and does not call the remote private key again to perform signing.
Number of Signatures
Jarsigner's number of signatures is calculated based on the actual successfully completed remote signing actions.
Generally:
| Operation | Number of Signatures |
|---|---|
| Successfully sign one JAR once | 1 time |
| Sign 3 JARs separately | 3 times |
| Sign the same JAR again | An additional 1 time |
jarsigner -verify Verify signature | 0 times |
Generate verify.jks | 0 times |
Therefore, the number of signatures mainly depends on how many successful signing operations were actually performed, rather than the number of source code files in the Java project.
For detailed rules, see Reference.
FAQ
Missing Access Key, Access Secret, or certificate number
Confirm that the current terminal has been set with:
SSLTRUS_JARSIGNER_ACCESS_KEY
SSLTRUS_JARSIGNER_ACCESS_SECRET
SSLTRUS_JARSIGNER_CERT_CODE
After setting the environment variables, you need to execute the signing command in the same terminal session.
Invalid option: -providerPath
If the following appears:
Invalid option: -providerPath
Typically indicates that JDK 8 is currently in use.
JDK 8 does not use the -providerPath parameter shown in the JDK 9 and later examples. Please use the JDK 8 commands provided in this article instead.
Unable to Load SSLTrusProvider
If a message indicates it cannot be loaded:
com.racent.codesign.SSLTrusProvider
Please check:
- Whether the
sslTrusJarsigner-<version>.jarpath is correct. - Whether the version number in the file name matches the actual file.
- Whether
JAVA_HOMEin the JDK 8 environment points to a complete JDK.
Certificate or alias not found
Please check:
- Whether the certificate number is correct.
- Whether the certificate number specified at the end of the command matches
SSLTRUS_JARSIGNER_CERT_CODE. - Whether the current Access Key and Access Secret have permission to use this certificate.
Remote signing request failed
Please check:
- Whether the current network can access the remote code signing service.
- Whether the proxy, firewall, and DNS configurations are normal.
- Whether the Access Key and Access Secret are correct.
- Whether the certificate number is correct.
- If a dedicated service address is used, whether
SSLTRUS_JARSIGNER_URLis configured according to the actual delivery information.
You may keep the complete error information when troubleshooting, but before submitting logs or error screenshots, remove or mask sensitive credentials such as Access Secret.
Timestamp failed
Confirm that the current network can access the timestamp server specified by -tsa.
If the business allows, you can temporarily remove:
-tsa <URL>
Sign again to determine whether the issue occurs in the remote code signing or the timestamp request phase.
Security notes
During Java integration, note the following:
- The Access Secret should be stored as a sensitive credential.
- Do not commit access credentials to Git repositories.
- Do not output the full Access Secret in logs.
verify.jksis for verification only and does not contain a private key that can be used for remote signing.- The local
sslTrusJarsignerProvider does not store code signing private keys. - Private key signing operations are always performed by the remote code signing service.
- In automated environments, inject access credentials using CI/CD Secrets or a dedicated credential management system.
Related integration methods
If you need to sign files other than Java JAR or XML files, choose another integration method based on your scenario:
| Scenario | Integration method |
|---|---|
| Sign EXE, DLL, MSI, and other files directly from the command line | Client tool |
| Microsoft SignTool, Visual Studio, and other Windows tools | Windows Provider |
| GitHub Actions, Electron Builder, and other automated builds | CI/CD and build tools |
| Develop your own remote signing client | API integration |