Code signing with the YubiKey on Windows


 

 

Description

This article explains how the YubiKey can be used to sign code in a Windows environment using common tools, such as SignTool or JarSigner. It is assumed that the YubiKey has already been provisioned with a code signing private key and the corresponding code signing certificate in one of its PIV slots (most commonly 9a or 9c).

 

manual-icon.svg Note: 
YubiKeys with firmware 5.7 are able to handle RSA1024-RSA4096 which can be used for code signing. YubiKeys with firmware lower than 5.7 would have to use Elliptic Curve keys (ECCP256 or ECCP384) instead, due to the updated minimum requirements for RSA keys used for code signing by the CA/B Forum in June 2023.

 

 

SignTool

Prerequisites

exclamation-triangle-line-icon.svg Warning: The YubiKey Smart Card Minidriver will block the PUK if the PUK is set to the default value (12345678). It is therefore important that the PUK is changed before using the YubiKey on a machine where the YubiKey Smart Card Minidriver is installed.

Procedure

    1. Plug in the YubiKey and locate the code signing certificate in the user's personal certificates store.
        ⊞ Win   +   r   certmgr.msc  → Certificates - Current User → Personal → Certificates 
    2. Obtain the signing certificate’s sha1 thumbprint
      1. Double-click on the code signing certificate in the user's personal certificates store →Details →Thumbprint 
      2. Mark the entire string and use  ctrl  +  c  to copy
    3. Open Command Prompt, navigate to the folder containing signtool.exe, and perform the signature:
      cd C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool
      Signtool sign /sha1 <sha1_thumbprint> /fd SHA256 /t <url_to_TimeStamp_Server> <file_to_sign>
      Example:
      signtool sign /sha1 83fe6c0f1f0d1db0a09ba2cd97015df7a852b4d3 /fd SHA256 /t http://timestamp.sectigo.com "C:\Users\YubicoTest\projects\file.exe"

 

bulb-light-icon.svg Tips: SignTool.exe requires that the PIN is entered once per signature when the private key is stored on a smart card. For large amounts of signatures, the YubiHSM2 should be used instead, which is a HSM and does not require a PIN to code sign with SignTool.

 

 

JarSigner

Prerequisites

 

 

 

ykcs11.conf

The pkcs11.config is a configuration file used by JarSigner to locate the PKCS#11 module that is used to interact with the token storing the private key (in this case, the YubiKey). This configuration file needs to be located in the same directory as the pkcs#11 library that is being used.

 

In this case, libykcs11.dll is being used (package in the Yubico PIV Tool). The default installation path in 64-bit Windows is:

C:\Program Files\Yubico\Yubico PIV Tool\bin

 

The contents of the file should look something like this:

name = ykcs11
library = "C:\\Program Files\\Yubico\\Yubico PIV Tool\\bin\\libykcs11.dll"

 

Procedure

  1. Open Command Prompt
  2. Navigate to the location of the libykcs11.dll file
    cd "C:\Program Files\Yubico\Yubico PIV Tool\bin"
  3. Check if the configuration is working and retrieve the signing certificate object label
    keytool -list -keystore NONE -storepass <PIV_PIN> -storetype PKCS11 -providerclass sun.security.pkcs11.SunPKCS11 -providerarg ykcs11.conf

    Example:
    C:\Program Files\Yubico\Yubico PIV Tool\bin>keytool -list -keystore NONE -storepass 123456 -storetype PKCS11 -providerclass sun.security.pkcs11.SunPKCS11 -providerarg ykcs11.conf
    Keystore type: PKCS11
    Keystore provider: SunPKCS11-ykcs11
    Your keystore contains 2 entries

    X.509 Certificate for PIV Attestation, PrivateKeyEntry,
    Certificate fingerprint (SHA-256): FB:FC:AB:E1:63:28:8A:B0:7E:8E:03:97:6C:1A:93:D6:E7:D6:D4:6C:D0:B8:34:A0:8F:AE:94:49:CC:10:AE:1E
    X.509 Certificate for PIV Authentication, PrivateKeyEntry,
    Certificate fingerprint (SHA-256): 0D:BF:B1:A3:CA:E3:1C:45:1B:D6:E4:84:D3:0A:BD:C6:5E:DF:DD:01:40:81:3B:0A:ED:68:98:70:D3:0D:C4:B1
     
  4. Sign with the following command. Ensure that you use the same PKCS#11 label that was returned by the keytool -list command, as this can vary slightly depending on which PKCS#11 module is being used. In this example, X.509 Certificate for PIV Authentication is used.
    jarsigner -keystore NONE -storepass <PIV_PIN> -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg <path_to_ykcs11.conf> -signedjar <path_to_signed_file_output> <unsigned_file_path> <signing_ykcs11_object_label> -tsa <TimeStamp_server_URL>
    Example:
    C:\Program Files\Yubico\Yubico PIV Tool\bin>jarsigner -keystore NONE -storepass 123456 -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg ykcs11.conf -signedjar C:\Users\Administrator\Documents\jarFiles\SignedFile.jar C:\Users\Administrator\Documents\jarFiles\unsigned.jar "X.509 Certificate for PIV Authentication" -tsa http://timestamp.digicert.com

    jar signed.

    The signer certificate will expire on 2024-07-08.
    The timestamp will expire on 2031-11-09.

 

 

 

Import the complete certificate chain to the YubiKey

In the case that your code signing certificate is issued by a public CA, ensure that the complete certificate chain is loaded onto the YubiKey.

This can be done using YubiKey Manager (CLI) (ykman) software, which allows you to import the CA root and intermediate certificates to the PIV slots for retired keys and certificates (82 and 83, for instance). In the case that your CA has multiple intermediate CA certificates, repeat the steps for slots 84 - 95.

 

Importing the certificate chain to the YubiKey:

  1. ykman piv certificates import 82 "<PATH\TO\ROOT\CERTIFICATE.pem>"
  2. ykman piv certificates import 83 "<PATH\TO\INTERMEDIATE\CERTIFICATE.pem>"

 

Verify that the CA and intermediate certificates were correctly imported:

ykman piv info
manual-icon.svg Note: In order to see the full certificate chain with CA root and intermediate certificates imported into slots 82 - 95, ensure that libykcs11.dll/.dylib/.so is used instead of other PKCS#11 modules, such as the OpenSC PKCS#11 module.

 

 

Troubleshooting

Refer to Troubleshooting Code Signing on Windows for troubleshooting steps.