Skip to main content

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 -signedjar to output to a new file and avoid overwriting the original JAR.
  • The example uses SHA256withRSA to complete code signing.
  • If a timestamp is not needed, you can remove -tsa and 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:

OperationNumber of Signatures
Successfully sign one JAR once1 time
Sign 3 JARs separately3 times
Sign the same JAR againAn additional 1 time
jarsigner -verify Verify signature0 times
Generate verify.jks0 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>.jar path is correct.
  • Whether the version number in the file name matches the actual file.
  • Whether JAVA_HOME in 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_URL is 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.jks is for verification only and does not contain a private key that can be used for remote signing.
  • The local sslTrusJarsigner Provider 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.

If you need to sign files other than Java JAR or XML files, choose another integration method based on your scenario:

ScenarioIntegration method
Sign EXE, DLL, MSI, and other files directly from the command lineClient tool
Microsoft SignTool, Visual Studio, and other Windows toolsWindows Provider
GitHub Actions, Electron Builder, and other automated buildsCI/CD and build tools
Develop your own remote signing clientAPI integration