Home » Wiki » How to Configure YubiHSM 2 for Java Code Signing

How to Configure YubiHSM 2 for Java Code Signing

by | Code Signing

How to Configure YubiHSM 2 for Java Code Signing

Using YubiHSM2 with Java Code Signing

Java code signing allows developers to cryptographically sign JAR files and Java applets to verify their integrity and authenticity. Signing code ensures that the code has not been modified since it was signed and provides trust in who signed the code.

YubiHSM 2 is a Hardware Security Module (HSM) that provides secure key storage and cryptographic operations to enable strong security for code signing. This guide will walk through the steps to configure YubiHSM 2 for code signing Java applications and JAR files.

Prerequisites

Before configuring YubiHSM 2 for Java code signing, ensure the following prerequisites are met:

  • The YubiHSM 2 device must be installed and accessible on the network. It must also be initialized and have authentication configured.
  • Administrative access to the YubiHSM 2 is available through the YubiHSM command line tools.
  • Java Runtime Environment (JRE) or Java Development Kit (JDK) installed to sign and verify Java code.
  • Java code signing tools like Eclipse, IntelliJ, Maven, Gradle, etc.
  • A code signing certificate is issued from a trusted certificate authority.

Generate Signing Key in YubiHSM 2

The first step is to generate a signing key within the YubiHSM 2. This key will be used to sign the Java code cryptographically.

  • Connect to the YubiHSM 2 via SSH or through the YubiHSM Command Line Interface.
  • At the prompt, generate an RSA 4096-bit private key:
generate asymmetric rsa_4096_key
  • Give the key a memorable label:
set label rsa_4096_key "Java Code Signing Key"
  • Set the domains for the key. Use the code signing domain:
set key-domains rsa_4096_key 1

This generates a 4096-bit RSA private key within the YubiHSM 2 hardware with the label “Java Code Signing Key.” This key will be used to sign the Java code.

Export Public Key for Signing

To sign the code, the public key corresponding to the private key generated above needs to be exported from YubiHSM 2.

export certificate rsa_4096_key JavaCodeSigningCert.pem
  • Transfer the exported JavaCodeSigningCert.pem file to the system used for Java code signing.

This certificate will be used by the signing tool and embedded into the signed JAR file.

Configure YubiHSM Connector

To enable Java code signing, the YubiHSM 2 Connector needs to be installed and configured. This allows the Java code signing utility to interface with the YubiHSM 2 for signing operations.

  • Install the YubiHSM 2 Connector on the system used for Java code signing.
  • Configure the Connector by editing /etc/yubihsm/connector.conf.

Set the following parameters:

connector.url: http://1.2.3.4:9010/connector
connector.keyLabel: Java Code Signing Key

Replace 1.2.3.4 with the IP address of your YubiHSM 2.

This configures the Connector to use the private key labeled “Java Code Signing Key” generated earlier.

  • Restart the YubiHSM Connector service for the changes to take effect.

Sign Java Code

With the private key generated in YubiHSM 2 and the connector configured, you can now sign the Java code. Update your code signing tool or build a system to utilize the YubiHSM Connector for signing operations.

For example, in Maven:

<project>
...
<build>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jarsigner-plugin</artifactId>
       <version>3.0.0</version>
       <executions>
         <execution>
           <id>sign</id>
           <goals>
             <goal>sign</goal>
             <goal>verify</goal>
           </goals>
           <configuration>
             <keystore>NONE</keystore>
             <storetype>PKCS11</storetype>
             <providerName>SunPKCS11-CryptoServer</providerName>
             <providerClass>sun.security.pkcs11.SunPKCS11</providerClass>
             <providerArg>http://127.0.0.1:9010</providerArg>
             <alias>Java Code Signing Key</alias>
           </configuration> 
         </execution>
       </executions> 
     </plugin>
   </plugins>
</build>
</project>

This configures Maven to utilize the YubiHSM Connector to sign using the “Java Code Signing Key.”

Build the Java project as usual. The JAR file will now be signed using the YubiHSM 2.

Verify Signed Code

To verify that the code was correctly signed, use the jarsigner tool that comes with the JDK:

jarsigner -verify signed.jar
smk 12345 Mon Sep 12 13:56:22 PDT 2022
X.509, CN=Yubico Code Signing

This verifies the signed JAR file and displays details about the code signing certificate.

You can also verify the signature programmatically using the JarSignature class:

import java.security.*;
import java.security.cert.*;
public class VerifySignature {
public static void main(String[] args) throws Exception {
   String jarFile = "signed.jar";
   JarFile jar = new JarFile(jarFile);
   JarEntry je = jar.getJarEntry("META-INF/MANIFEST.MF");
   Manifest manifest = new Manifest(jar.getInputStream(je));
   Attribute attr = manifest.getMainAttributes().get(Attributes.Name.SIGNATURE_VERSION);
   if (attr == null) {
     System.out.println("No signature");
     return;
   }
   // Get certificate
   Certificate[] certs = je.getCertificates();
   if (certs == null) {
     System.out.println("No certificate");
     return;
   }
   // Verify certificate
   certs[0].verify(cert.getPublicKey());
   // Verify signature
   JarSignature signature = new JarSignature(manifest, certs);
   if(!signature.verifySignature()) {
     System.out.println("Invalid signature");
   }
   else {
     System.out.println("Valid signature");
   }
}
}

This loads the signed JAR file, extracts the signature information and certificate, and verifies the cryptographic signature.

How to Configure YubiHSM Code Signing Policy

For additional security, you can configure a code signing policy within YubiHSM 2. This restricts how the code signing key can be used.

Create a policy file codesign_policy.txt:

Policy:
# Only allow SHA-256 digest
HashAlgorithms: ["SHA-256"]
# Only sign data less than 5 MB 
MaxDataSize: "5 MB"
# Expire the policy after 1 year
  Expiration: "2023-01-01T00:00:00Z"

Load and apply this policy to the code signing key:

yubihsm> import policy codesign_policy.txt
yubihsm> set key-policy rsa_4096_key 1

Now, signature creation will only be allowed if it meets the policy criteria.

Final Thoughts

Configuring YubiHSM 2 to sign Java code provides robust security by storing private keys in secure hardware. Keys are protected from compromise and misuse. Various integrations allow the YubiHSM 2 to sign code during the build process. Policies add further protection on how keys can be used for signing. With YubiHSM 2, organizations can securely sign Java applications, JARs, applets, and frameworks.

FAQs

Can I generate the private key outside of YubiHSM 2 instead of generating it within the HSM?

Yes, you can generate the private key externally, then import and label it in YubiHSM 2. However, generating keys inside YubiHSM 2 provides the highest security.

Do I need to install anything on the build server to integrate with YubiHSM 2 code signing?

To enable integration, the YubiHSM Connector needs to be installed and configured on the build server. The connector provides the interface between the build tools and YubiHSM 2.

What cryptographic algorithms and key sizes does YubiHSM 2 support for code signing?

YubiHSM 2 supports RSA and ECC algorithms for code signing keys. Recommended key sizes are:

  • RSA 2048 bits or larger
  • ECC P-256 or P-384

Larger key sizes provide greater security but take longer to generate and sign with.

Can I store code signing certificates and keys for multiple applications in YubiHSM 2?

Yes, YubiHSM 2 can hold keys for signing numerous applications and packages. Be sure to use unique label names for each one.

Does YubiHSM 2 integrate with common code signing utilities like jarsigner and SignTool?

Yes, the YubiHSM Connector provides a PKCS#11 interface that is compatible with jarsigner and SignTool for signing operations using keys in YubiHSM 2.

Can I store code signing keys for multiple applications from different developers on one YubiHSM 2?

Yes, when properly partitioned, one YubiHSM 2 can hold keys for many different applications and development teams. To restrict cross-signing, assign each key to a different domain or credential group.

What happens if the code signing certificate expires? Do I need to re-sign all my code?

When the code signing certificate expires, you should generate a new certificate and sign future releases. However, the existing signed code remains valid and verified using the original expired certificate—no need to re-sign released artifacts.

Is there a sample code available for integrating YubiHSM 2 with Java code signing workflows?

Yes, Yubico provides code examples on GitHub for integrating YubiHSM with common Java build tools like Maven and Gradle. These serve as a good starting point for your integrations.

Priya Mervana

Priya Mervana

Verified Badge Verified Web Security Experts

Priya Mervana is working at SSLInsights.com as a web security expert with over 10 years of experience writing about encryption, SSL certificates, and online privacy. She aims to make complex security topics easily understandable for everyday internet users.