Skip to main content
JSign applies an Authenticode signature to Windows artifacts using a key that stays on the CryptoHub. It runs on any JVM, so you can sign from a Linux or a Windows host. The examples in this section sign a PowerShell script (hello.ps1), because a script is the simplest artifact to create and inspect. JSign also signs Windows PE files (.exe and .dll), MSI installers, CAB archives, and APPX and MSIX packages. The commands are the same for any supported artifact type; only the file name changes.
JSign takes the SunPKCS11 provider configuration (pkcs11.cfg) as its --keystore argument, not the Futurex library configuration (fxpkcs11.cfg). Both files must be correct: --keystore lets JSign build the provider, and FXPKCS11_CFG lets the Futurex library find the CryptoHub. If you pass fxpkcs11.cfg to --keystore, JSign cannot construct the provider.

Sign a file

Before signing, confirm the CryptoHub-resident signing key is visible to Java and copy its alias.
1
Run the following keytool command to list the keys on the CryptoHub that the configured identity has access to. The -providerArg flag passes the pkcs11.cfg file you created earlier:
Shell
When prompted for the KeyStore password, enter the CryptoHub identity password configured inside the <CRYPTO-OPR-PASS> tag in the fxpkcs11.cfg file.
The response should be similar to the following:
Shell
Copy the alias from this output exactly as it appears, including the numeric segment and the colon. The alias JSign requires is the full <alias>-<id>:<alias> form the CryptoHub assigned, not the short -alias value you passed to keytool -genkeypair. The <id> segment is generated per key, so it differs in your environment from the example shown here.
2
Create a test artifact to sign.On Linux:
Shell
On Windows, use PowerShell:
PowerShell
3
Run JSign to sign the artifact with the CryptoHub-resident key. Replace the alias with the value you copied in step 1:
Shell
On Windows, run the equivalent command in a Command Prompt or PowerShell window:
Command Prompt
Replace <alias-from-keytool-list> with the full alias you copied in step 1. The value must match the alias keytool -list displayed, including the numeric segment and the colon, and it differs in your environment. Replace <PIN> with the CryptoHub identity password (PKCS #11 PIN) from the <CRYPTO-OPR-PASS> tag in fxpkcs11.cfg.
Unlike keytool, JSign does not prompt for the PIN, so you must supply it. A PIN passed on the command line is visible in your shell history and in the system process list. In an automated pipeline, read it from a secret your CI system injects rather than writing it into a script.
If the signing succeeds, the response is:
Shell
--alg SHA-384 sets the digest algorithm for the Authenticode signature. JSign also accepts SHA-256. Match this value to your organization’s code signing policy.
For production signing, consider adding an RFC 3161 timestamp with JSign’s --tsaurl option so signatures remain verifiable after the signing certificate expires. Refer to the JSign documentation for the timestamping options.
JSign’s --certfile option adds certificates to the signature’s chain. It cannot substitute for the certificate that must exist on the token alongside the private key, and it does not make an older JSign release embed the signer certificate. If keytool -list does not show a PrivateKeyEntry, resolve that first; --certfile does not work around it.

Verify the signature

Verify the signature in two ways: confirm the signature block is present in the artifact, and validate the Authenticode signature itself.

Confirm the signature block

On either operating system, inspect the signed script. JSign appends the Authenticode signature to a PowerShell script as a comment block at the end of the file. On Linux:
Shell
On Windows:
Command Prompt
The file ends with a signature block delimited as follows:
hello.ps1
This confirms JSign wrote a signature into the artifact. It does not validate the signature cryptographically.

Validate the Authenticode signature

Authenticode validation is a Windows operation. On a Windows host, run the following PowerShell cmdlet against the signed artifact:
PowerShell
The cmdlet returns a Status field, a SignatureType field, and a SignerCertificate field.
SignatureType reads Authenticode, and SignerCertificate shows the subject of the certificate you generated, which confirms the signature came from the CryptoHub-resident key:
PowerShell
The certificate this guide generates is self-signed, so Windows does not trust its issuer and Status reports the untrusted-root result shown above rather than Valid. This is expected for a test certificate and does not indicate a signing failure. Adding the test certificate to the Trusted Root Certification Authorities store on the verifying host changes Status to Valid and StatusMessage to Signature verified. For production signing, use a certificate issued by a code signing CA the verifying hosts already trust.
If SignatureType reads None and StatusMessage reads The certificate for the signer of the message is invalid or not found, the signing tool did not embed the signer certificate in the signature. Confirm you signed with JSign 7.4 or later; JSign 7.1 omits the certificate, and --certfile does not compensate for it.
JSign has no verification subcommand. On Linux, the JSign exit status, the Adding Authenticode signature output, and the signature block in the artifact together confirm the operation completed. Full Authenticode chain validation requires a Windows host.