Jsign is an open-source, platform-independent Java tool for Microsoft Authenticode code signing. Jsign is easy to integrate with build systems like Maven, Gradle, and Ant, or can be used directly from the command line.
In this how-to we’ll cover using Jsign from the Linux command line for OV/IV code signing and EV code signing. Because Jsign is Java based, you can also use it on Windows and MacOS systems.
Install Jsign
First, you’ll have to download and install Jsign. The Jsign website includes links to Debian and RPM packages for easy installation on most popular Linux systems, as well as a .jar
file.
OV/IV Code Signing
For OV/IV code signing you can use a certificate stored in a Java keystore or PKCS#12 (PFX) file. In all code examples below, replace the values shown in ALL-CAPS with your actual values.
- First, use the
keytool
command to get thealias
value to use when signing:keytool -list -v -keystore PKCS12-FILE.p12 -storetype PKCS12 -storepass PKCS12-PASSWORD
- Check the output of your
keytool
command for a line beginning withAlias name:
.Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 1 entry Alias name: 1 Creation date: Jan 18, 2021 Entry type: PrivateKeyEntry Certificate chain length: 4 ...
In the above example,
Alias name
is1
. - Use a command like the following to sign and timestamp a file:
jsign
command installed system-wide:jsign --keystore KEYSTORE.p12 --alias ALIAS-NAME --storetype PKCS12 --storepass PKCS12-PASSWORD --tsaurl http://ts.ssl.com --tsmode RFC3161 FILE-TO-SIGN
- With Jsigner
.jar
file:java -jar jsign-3.1.jar --keystore KEYSTORE.p12 --alias ALIAS-NAME --storetype PKCS12 --storepass PKCS12-PASSWORD --tsaurl http://ts.ssl.com --tsmode RFC3161 FILE-TO-SIGN
- If your command is successful, you should see output like the following:
Adding Authenticode signature to example.exe
If you encounter this error:
The timestamp certificate does not meet a minimum public key length requirement
, you should contact your software vendor to permit timestamps from ECDSA keys.If there is no way for your software vendor to allow for the normal endpoint to be used, you can use this legacy endpoint
http://ts.ssl.com/legacy
to get a timestamp from an RSA Timestamping Unit.EV Code Signing
You can also use Jsign with an EV code signing certificate. The example here uses an SSL.com EV code signing certificate installed on a FIPS 140-2 validated security key USB token.
- First, make sure that OpenSC is installed on your system so it can communicate with your token via the PKCS#11 API. On Debian-based distros like Ubuntu you can install OpenSC with
apt
:sudo apt install opensc
- Next, create a configuration file. The name of the file is arbitrary, but for the example commands below we’ll use
eToken.cfg
. Note that the path toopensc-pkcs11.so
may vary in your OpenSC installation, so check before creating the config file.name = OpenSC-PKCS11 description = SunPKCS11 via OpenSC library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so slotListIndex = 0
- Use the
keytool
command to get thealias
value to use when signing:keytool -list -v -keystore NONE -storetype PKCS11 -storepass TOKEN-PIN -providerClass sun.security.pkcs11.SunPKCS11 -providerArg eToken.cfg
- Check the output of your
keytool
command for a line beginning withAlias name:
. If your token contains multiple certificates, check the validity dates and issuer in the output against your certificate. Note that EV code signing certificates issued on YubiKey from SSL.com should have an alias name ofCertificate for PIV Authentication
.Alias name: Certificate for PIV Authentication Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: OID.1.3.6.1.4.1.311.60.2.1.3=US, OID.1.3.6.1.4.1.311.60.2.1.2=Nevada, OID.2.5.4.15=Private Organization, CN=SSL Corp, SERIALNUMBER=NV20081614243, O=SSL Corp, L=Houston, ST=TX, C=US Issuer: CN=SSL.com EV Code Signing Intermediate CA RSA R2, O=SSL Corp, L=Houston, ST=Texas, C=US Serial number: 7299f93a57bac3c6570f781580e63172 Valid from: Fri Apr 17 12:46:04 EDT 2020 until: Sat Apr 17 12:46:04 EDT 2021
- Use a command like the following to sign and timestamp a file:
jsign
command installed system-wide:jsign --keystore eToken.cfg --alias "Certificate for PIV Authentication" --storetype PKCS11 --storepass TOKEN-PIN --tsaurl http://ts.ssl.com --tsmode RFC3161 FILE-TO-SIGN
- With Jsigner
.jar
file:java -jar jsign-3.1.jar --keystore eToken.cfg --alias "Certificate for PIV Authentication" --storetype PKCS11 --storepass TOKEN-PIN --tsaurl http://ts.ssl.com --tsmode RFC3161 FILE-TO-SIGN
- If your command is successful, you should see output like the following:
Adding Authenticode signature to example.exe
If you encounter this error:
The timestamp certificate does not meet a minimum public key length requirement
, you should contact your software vendor to permit timestamps from ECDSA keys.If there is no way for your software vendor to allow for the normal endpoint to be used, you can use this legacy endpoint
http://ts.ssl.com/legacy
to get a timestamp from an RSA Timestamping Unit.Verify Digital Signature
- You can verify that your digital signature is valid by viewing the signature details in Windows.
- You can also use SignTool in Windows to verify the digital signature.
signtool.exe verify /pa 'C:\Users\Aaron Russell\Desktop\example.exe' File: C:\Users\Aaron Russell\Desktop\example.exe Index Algorithm Timestamp ======================================== 0 sha256 RFC3161 Successfully verified: C:\Users\Aaron Russell\Desktop\example.exe