AWS KMS Code Signing: setup guide
This guide covers setting up AWS KMS for Code Signing. AWS KMS provides HSM-backed keys (FIPS 140-2 Level 3 since May 2023) at a low monthly cost, but requires Jsign for signing and helper tools for CSR generation.
Works with both OV and EV Code Signing certificates from DigiCert and GlobalSign.
When to use AWS KMS for Code Signing
AWS KMS is a good choice if your organisation is already invested in AWS infrastructure and you want to keep your signing keys within the AWS ecosystem. The setup is more involved than Azure Key Vault, and signing requires Jsign (no native signtool.exe support).
AWS KMS (~$1/month)
- ✓ RSA 4096, FIPS 140-2 Level 3
- ✓ Low cost, pay-per-use
- — Jsign only (no signtool.exe)
- — CSR requires helper tools
AWS CloudHSM (~$14,000/year)
- ✓ Full PKCS#11 + signtool.exe support
- ✓ Dedicated HSM hardware
- — Prohibitively expensive
- — Only practical with existing HSM infra
This guide covers AWS KMS (the affordable option). If you need signtool.exe support and are not already on AWS, Azure Key Vault is the easier and better-supported path.
Prerequisites
- ✓ AWS account with permissions to create KMS keys
- ✓ AWS CLI v2 installed and configured. Download from aws.amazon.com/cli ↗
- ✓ Java 11+ (for Jsign)
- ✓ Go or Python (for CSR generation helper tools)
- ✓ A Code Signing certificate from FairSSL (DigiCert or GlobalSign). See products below
Step 1: Create an asymmetric KMS key
aws kms create-key \ --key-spec RSA_4096 \ --key-usage SIGN_VERIFY \ --description "Code Signing key" \ --tags TagKey=Purpose,TagValue=CodeSigning
Note the KeyId from the response. You will need this for all subsequent commands.
# Create an alias for easier reference aws kms create-alias \ --alias-name alias/codesign \ --target-key-id YOUR_KEY_ID
Key settings
- Key spec:
RSA_4096(required for Code Signing) - Key usage:
SIGN_VERIFY(signing only, not encryption) - Protection: All AWS KMS keys are HSM-backed (FIPS 140-2 Level 3 since May 2023)
The private key never leaves the HSM. AWS KMS does not support key export. All signing operations are performed inside the HSM.
Step 2: Configure IAM permissions
Create an IAM user or role for your signing pipeline with permission to use the KMS key.
Minimum IAM policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Sign",
"kms:GetPublicKey",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:REGION:ACCOUNT:key/YOUR_KEY_ID"
}
]
}
For CSR generation, you also need kms:GetPublicKey. For the signing step, kms:Sign is sufficient.
Step 3: Generate CSR
AWS KMS does not have a built-in CSR generation feature (unlike Azure Key Vault). You need a helper tool that extracts the public key from KMS and creates a properly formatted CSR.
Option A: aws-kms-sign-csr (Go)
A lightweight Go tool that generates a CSR signed by the KMS key.
# Install go install github.com/AdrianHenworthy/aws-kms-sign-csr@latest # Generate CSR aws-kms-sign-csr \ --key-id alias/codesign \ --subject "CN=Your Company Name" \ --out codesign.csr
Option B: Manual with AWS CLI + OpenSSL
Extract the public key from KMS and create a CSR manually:
# Get the public key aws kms get-public-key \ --key-id alias/codesign \ --output text \ --query PublicKey | base64 --decode > public-key.der # Convert to PEM openssl rsa -pubin -inform DER -in public-key.der -out public-key.pem # Create CSR (requires signing via KMS, not straightforward) # The aws-kms-sign-csr tool handles this automatically
The manual approach is complex because the CSR itself must be signed by the private key,
which requires calling kms:Sign on the CSR's TBS (to-be-signed) data.
The dedicated tools handle this correctly.
Step 4: Order certificate and submit CSR
- 1 Order a Code Signing certificate from FairSSL. Choose DigiCert or GlobalSign, OV or EV. See products below.
- 2 Submit the CSR file from step 3 during the order process.
- 3 Complete organisation validation. FairSSL handles the validation process.
- 4 Receive the signed certificate from the CA. Save it as a PEM file (e.g.
codesign-cert.pem).
Step 5: Install Jsign and sign
Jsign ↗ is the primary signing tool for AWS KMS code signing. It is free, open-source, and works on Windows, macOS and Linux. Requires Java 11+.
Sign with Jsign
jsign --storetype AWS \ --keystore "eu-west-1" \ --alias "alias/codesign" \ --certfile codesign-cert.pem \ --tsaurl http://timestamp.digicert.com \ --tsmode RFC3161 \ MyApplication.exe
Parameter reference
--storetype AWSUse AWS KMS backend--keystoreAWS region where the key is located--aliasKMS key alias or key ID--certfileSigned certificate file from the CA (PEM format)--tsaurlRFC 3161 timestamp server
Jsign uses the standard AWS credential chain: environment variables (AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY), AWS CLI configuration, instance profiles, or ECS task roles.
CI/CD integration
Jsign runs in any CI/CD pipeline with Java installed. Store your AWS credentials as secret pipeline variables or use IAM roles for keyless authentication.
GitHub Actions example
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Sign executable
run: |
jsign --storetype AWS \
--keystore eu-west-1 \
--alias alias/codesign \
--certfile codesign-cert.pem \
--tsaurl http://timestamp.digicert.com \
--tsmode RFC3161 \
"output/MyApplication.exe" Docker-based signing
For containerised pipelines, use a Docker image with Java and Jsign pre-installed:
FROM eclipse-temurin:17-jre
RUN curl -sL https://github.com/ebourg/jsign/releases/download/6.0/jsign-6.0.jar \
-o /usr/local/lib/jsign.jar
ENTRYPOINT ["java", "-jar", "/usr/local/lib/jsign.jar"] Timestamping
Always include an RFC 3161 timestamp when signing. Code Signing certificates have a maximum validity of 459 days, but timestamped signatures are valid indefinitely.
Recommended timestamp servers
http://timestamp.digicert.com(recommended)http://timestamp.globalsign.com/tsa/r6advanced1
Troubleshooting
"AccessDeniedException" when signing
The IAM user/role is missing kms:Sign permission on the key.
Check the IAM policy and ensure it targets the correct key ARN.
"InvalidKeyUsageException"
The KMS key was created with ENCRYPT_DECRYPT usage instead of SIGN_VERIFY.
You need to create a new key with the correct key usage. KMS key usage cannot be changed after creation.
CSR generation fails
Verify that the IAM user has kms:GetPublicKey permission. Also check that
the key spec is RSA_4096 and the region is correct.
Jsign reports "no provider for storetype AWS"
You need Jsign version 5.0 or later for AWS KMS support. Download the latest version from the Jsign website. Ensure the AWS SDK dependencies are available on the classpath.
Code Signing certificates
OV Code Signing
DigiCert CodeSign OV
DigiCert OV Code Signing. Works with AWS KMS via Jsign.
GlobalSign CodeSign
GlobalSign OV Code Signing. Works with AWS KMS via Jsign.
EV Code Signing
Frequently asked questions
Find answers to the most common questions about SSL certificates and FairSSL.
Ready to sign with AWS KMS?
Create a free account and issue your first certificate in under 10 minutes.