Skip to main content

Java Integration

sslTrus provides sslTrusJarsigner Java Provider, which can be used with the jarsigner tool bundled with the JDK to complete Java JAR file signing through a remote code signing service.

During the signing process, the code signing private key is always kept in the cloud HSM. The local side is responsible for generating the data to be signed and the signature structure, and completes the private key signing by calling the remote service through the sslTrusJarsigner Provider.

In addition to JAR signing, sslTrusJarsigner also provides XMLDSig signing capabilities, which can be used in XML digital signature scenarios.

Preparation​

Before use, please prepare:

  • JDK 8 or higher.
  • sslTrusJarsigner-<version>.jar.
  • Access Key.
  • Access Secret.
  • Certificate number (Cert Code).
  • The JAR file or XML file to be signed.

<version>, access credentials, certificate number, and file paths in the examples in this article all need to be replaced with actual values.

Download sslTrusJarsigner​

Download the latest release package from the sslTrusJarsigner releases 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 validation before use.

Check the runtime environment​

First, confirm that Java and the jarsigner included with the JDK 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 you have installed the full JDK rather than a runtime environment that contains only the Java Runtime.

Configure access credentials​

sslTrusJarsigner reads the access credentials and certificate number for 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 service personnel have 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, this variable does not need to be set.

The Access Secret is sensitive credential information 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 example below 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 the Provider in a different way from JDK 9 and later versions.

First, confirm:

JAVA_HOME

Point 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, 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 to avoid overwriting the original JAR.
  • The example uses SHA256withRSA to complete code signing.
  • When a timestamp is not required, you can remove -tsa and the timestamp address that follows it.

Timestamp​

It is recommended to add a trusted timestamp when signing JARs for official release.

Used in the example:

http://timestamp.sectigo.com

Corresponding parameter:

-tsa http://timestamp.sectigo.com

Timestamps are used to prove when a 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 conforms to your actual signing policy.

For information about different timestamp services and production environment selection, refer to Reference Materials.

XML Signing​

sslTrusJarsigner also provides XML digital signing capabilities.

XML files can be signed using the sign-xml command to generate an XMLDSig Enveloped Signature.

During signing, the local machine is responsible for generating the digest and signature structure required by XMLDSig, 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 contains only the leaf certificate. If the recipient requires the XML to include the full certificate chain, you can add the --full-chain parameter at the end of the command.

After execution is complete:

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 for verifying 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 used only 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 the 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 the JAR, you can run:

jarsigner -verify -verbose -certs "app-signed.jar"

Verifying a signature only checks the existing signature and does not call the remote private key again to perform signing.

Signature Count​

Jarsigner's signature count is calculated based on the actual number of successfully completed remote signing actions.

Typically:

OperationSignature Count
Successfully sign one JAR once1
Sign 3 JARs separately3
Sign the same JAR once moreAdds 1 more
jarsigner -verify verify signature0
Generate verify.jks0

Therefore, the signature count mainly depends on how many successful signing operations are 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 set:

SSLTRUS_JARSIGNER_ACCESS_KEY
SSLTRUS_JARSIGNER_ACCESS_SECRET
SSLTRUS_JARSIGNER_CERT_CODE

After setting environment variables, you need to execute the signing command in the same terminal session.

Invalid option: -providerPath​

If the following appears:

Invalid option: -providerPath

It usually indicates that JDK 8 is currently in use.

JDK 8 does not use the -providerPath parameter from the JDK 9 and later examples. Please use the JDK 8 commands provided in this article instead.

Unable to Load SSLTrusProvider​

If it prompts that 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 full 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 the 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, you should remove or mask sensitive credentials such as the Access Secret.

Timestamp failed​

Confirm that the current network can access the timestamp server specified by -tsa.

If your business allows it, you can temporarily remove:

-tsa <URL>

Execute the signing again to determine whether the issue occurs during remote code signing or at the timestamp request stage.

Security Notes​

During Java integration, please note the following:

  • The Access Secret should be stored as a sensitive credential.
  • Do not commit access credentials to a Git repository.
  • 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, it is recommended to 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, you can choose other integration methods based on your actual 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 build toolsCI/CD and Build Tools
Develop your own remote signing clientAPI Integration