Windows Code Signing with Akeyless
This guide provides step-by-step instructions to set up code signing using Akeyless for PKI certificate issuance and the Akeyless Key Storage Provider (KSP) on Windows. It includes creating secrets in Akeyless, generating certificates, configuring the KSP, and performing a complete uninstall/reinstall of the Akeyless KSP for troubleshooting or clean setup.
All commands assume you have the Akeyless CLI installed and authenticated. Replace placeholder paths (/YourCompany/) with your own organization-specific paths in Akeyless.
Part 1: Create Secrets and Issue Code-Signing Certificate in Akeyless
Create Root Key for PKI Issuer
akeyless create-dfc-key \
--profile default \
--name /YourCompany/code-signing/root-key \
--alg RSA2048 \
--split-level 2 \
--certificate-ttl 30 \
--generate-self-signed-certificate trueCreate 4096-bit Key and Generate CSR
akeyless generate-csr \
--profile default \
--split-level 2 \
--name /YourCompany/code-signing/signing-key \
--generate-key \
--key-type dfc \
--alg RSA4096 \
--common-name code.sign.example.com | Out-File -Encoding ascii signing.csrCreate PKI Certificate Issuer
akeyless create-pki-cert-issuer \
--profile default \
--name /YourCompany/code-signing/pki-issuer \
--allowed-domains code.sign.example.com \
--signer-key-name /YourCompany/code-signing/root-key \
--code-signing-flag \
--ttl 600d \
--destination-path /YourCompany/code-signingIssue the 4096-bit Certificate
akeyless get-pki-certificate \
--profile default \
--cert-issuer-name /YourCompany/code-signing/pki-issuer \
--csr-file-path signing.csr \
> signing.pemExample Configuration File (sqlcrypt.conf)
Create a file named sqlcrypt.conf in a secure location (example C:\Akeyless\conf\sqlcrypt.conf):
akeyless_url = "https://gw-aws.lm.cs.akeyless.fans/api/v2"
base_item_path = "/YourCompany/"
log_path = ""
use_classic_keys = false
[ksp]
signing_key_item = "/YourCompany/code-signing/signing-key"
signing_cert_item = "/YourCompany/code-signing/signing-cert"
[auth]
access_type = "access_key"
access_id = ""
access_key = "*****************************"
Notes
Updatebase_item_pathto match your Akeyless path. Fill in your actualaccess_idandaccess_key. The certificate will be automatically stored in Akeyless at the path specified insigning_cert_item.
Part 2: Akeyless KSP – Full Uninstall and Install
This procedure ensures a clean removal and reinstallation of the Akeyless KSP. It clears registry entries, files, and cached provider information.
Important:
- Run all PowerShell commands from an elevated PowerShell (Run as Administrator).
- A reboot is required after uninstall and after install for changes to take effect reliably.
- Have the Akeyless KSP MSI file ready (e.g., downloaded from your build artifacts).
Define Variables
$msi = "C:\Path\To\AkeylessKspInstaller.msi" # Update to your MSI location
$prov = "Akeyless KSP"
$logInstall = Join-Path $env:TEMP "AkeylessKspInstall.log"
$logUninst = Join-Path $env:TEMP "AkeylessKspUninstall.log"Verify:
$msi
$logInstall
Test-Path $msi # Should return TrueFull Uninstall
$uninstRoots = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
)
$app = Get-ChildItem $uninstRoots | ForEach-Object { Get-ItemProperty $_.PSPath } |
Where-Object { $_.DisplayName -like "Akeyless KSP*" } | Select-Object -First 1
$app.DisplayName
$app.PSChildName # This is the ProductCode GUID
msiexec /x $app.PSChildName /l*v "$logUninst"
$LASTEXITCODEExpected exit code: 0 or 3010 (reboot required).
Reboot the machine now. Do not skip this step.
Verify Uninstall (after reboot)
Run these checks – all should show the provider is gone:
certutil -csplist | findstr /i "Akeyless" # No output
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Providers\Akeyless KSP" /s # Key not found
reg query "HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Akeyless KSP" /s # Key not found
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\Default\00010001\KEY_STORAGE" /v Providers # No Akeyless KSP
Test-Path "C:\Windows\System32\AkeylessKsp.dll" # False
Test-Path "C:\Program Files\Akeyless\Akeyless KSP\akeyless-ksp-cert-helper.exe" # False(Optional) Clean leftover certificate bindings:
certutil -store -v My | Select-String -Pattern "Provider = Akeyless KSP" -Context 6,10
# If any found, run your cleanup script or manually re-bind certificatesFull Install
Install the MSI
msiexec /i "$msi" IMPORT_CERT=0 /l*v "$logInstall"
$LASTEXITCODE(Alternative robust version if issues occur:)
Start-Process -FilePath "msiexec.exe" -Verb RunAs -Wait -ArgumentList @(
"/i", $msi, "IMPORT_CERT=0", "/l*v", $logInstall
)
$LASTEXITCODEExpected exit code: 0 or 3010.
Reboot the machine now.
Verify Installation (after reboot)
Get-Item "C:\Windows\System32\AkeylessKsp.dll" | Select FullName,Length,LastWriteTime
Get-Item "C:\Program Files\Akeyless\Akeyless KSP\akeyless-ksp-cert-helper.exe" | Select FullName,Length,LastWriteTime
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Providers\Akeyless KSP" /s
reg query "HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Akeyless KSP" /s
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Cryptography\Configuration\Local\Default\00010001\KEY_STORAGE" /v Providers # Contains Akeyless KSP
certutil -csplist | findstr /i "Akeyless" # Shows "Provider Name: Akeyless KSP"Sync Certificate and Test Signing
Run the Helper to Sync/Bind Certificate
$helper = "C:\Program Files\Akeyless\Akeyless KSP\akeyless-ksp-cert-helper.exe"
& $helper --config-path "C:\Akeyless\conf\sqlcrypt.conf" sync-cert --store-scope machine --store-name My
"exit=$LASTEXITCODE" # Should be 0Find Your Certificate Thumbprint
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.HasPrivateKey } |
Select-Object Subject, Thumbprint, NotAfter | Format-Table -Auto
# Example filter:
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*code.sign.example.com*" } |
Select-Object Subject, Thumbprint, NotAfter | Format-Table -AutoSet variable:
$thumb = "YOUR_THUMBPRINT_HERE"Confirm Binding
(Get-Item "Cert:\LocalMachine\My\$thumb").HasPrivateKey
certutil -store -v My $thumb | findstr /i "Provider Container"Expected: Provider = Akeyless KSP
Sign a Test File
$file = "C:\Temp\hello.dll" # Place a test DLL here
signtool sign /debug /v /sm /s My /sha1 $thumb /fd SHA256 `
/tr "http://timestamp.digicert.com" /td SHA256 $file
"sign exit=$LASTEXITCODE" # Should be 0Validate Signature
$sig = Get-AuthenticodeSignature $file
$sig.Status
$sig.SignerCertificate.Subject
$sig.SignerCertificate.ThumbprintVerify Signature (with Trust)
signtool verify /pa /v $fileIf chain is not trusted, import your root CA into the machine's Trusted Root Certification Authorities store.
Updated about 4 hours ago
