Code Signing Certificate Resource Code Signing Best Practices & Security Resources

How to Sign an Azure Application with SignTool Using KSP Library

Your Azure application build is complete. The installer is packaged, the pipeline has run, and it is ready for distribution. Then Windows Defender SmartScreen evaluates it — and presents the end user with an "Unknown Publisher" warning that stops the install cold. If you have been in cloud-native software delivery long enough, you know this moment. The fix is not complicated, but it must be done correctly, and in 2024 the standards for what "correctly" means changed significantly.

To sign an Azure application with SignTool using a KSP library, you configure SignTool to route the signing operation through a cloud-based Key Storage Provider — such as DigiCert KeyLocker — so the private key never resides on your local machine or build agent. The result is a cryptographically valid, CA/B Forum-compliant signature that satisfies both Windows trust requirements and enterprise security policy.

I have been working at the intersection of Azure application delivery and code signing certificate infrastructure for over a decade. This guide covers the complete workflow: what a KSP library actually is, why this architecture is now mandatory, and both signing methods — certificate file and certificate thumbprint — with every command you need to execute them reliably in a production environment.

What Is a KSP Library and Why Does It Matter for Azure App Signing?

A KSP (Key Storage Provider) library is a Windows CryptoAPI Next Generation (CNG) plugin that allows SignTool and other signing tools to interface with external key stores — including cloud HSMs — rather than requiring the private key to reside locally on disk or a physical USB token.

When SignTool executes a signing operation, it does not directly handle the private key. Instead, it asks the operating system's CNG layer to perform the cryptographic operation. The KSP is the CNG plugin that handles that request — and if the KSP is configured to point at a cloud key store like DigiCert KeyLocker or Azure Key Vault, the signing operation is completed in the cloud. The private key never leaves the HSM boundary.

For Azure application workflows, the two primary KSP options are DigiCert KeyLocker KSP and the Azure Key Vault CNG Provider. Both bridge SignTool to cloud-based key storage, but they differ in authentication model, latency characteristics, and suitability for CI/CD pipelines. This guide focuses on DigiCert KeyLocker, which is the most widely deployed option for code signing certificate workflows.

Why Signing Azure Applications with a KSP Library Is Now a Compliance Requirement

Since June 1, 2023, the CA/Browser Forum Baseline Requirements (Section 16.3) mandate that all OV and EV code signing certificate private keys be stored on hardware meeting FIPS 140-2 Level 2 or equivalent standards — including cloud HSMs. Certificate Authorities can no longer issue code signing certificates where the private key is generated locally in software. This is not guidance; it is a hard issuance requirement.

Beyond compliance, there are three practical reasons why cloud KSP signing is the right architecture for Azure application workflows:

  • Private key security: A private key stored on a developer workstation or build server is a supply chain attack vector. Cloud HSMs with access control and audit logs eliminate that exposure entirely.
  • SmartScreen reputation: Unsigned or improperly signed applications trigger Microsoft Defender SmartScreen warnings that reduce user trust and suppress install conversion rates, particularly for ISVs distributing through web channels.
  • Pipeline scalability: KSP-based signing integrates directly into Azure DevOps pipelines and GitHub Actions without USB token dependencies or manual signing handoffs, which are the two most common failure points in enterprise signing workflows.
  • Timestamp validity: Signatures produced through a trusted KSP and timestamped against an RFC 3161 server remain cryptographically valid after the signing certificate expires — critical for long-lived software artifacts.

Prerequisites: What You Need Before You Start

Before executing any signing command, confirm that all of the following are in place. Missing a single prerequisite — particularly the KSP registration — is the most common reason SignTool fails silently or returns a CNG provider error.

  • Windows operating system: Windows 10/11 or Windows Server 2019/2022
  • SignTool installed: via the Windows SDK — confirm with signtool.exe /? from an elevated command prompt
  • DigiCert KeyLocker client: installed and authenticated — the smctl binary must be in your system PATH
  • Keypair alias: the identifier for your private key in KeyLocker (found in your KeyLocker dashboard)
  • Certificate file or certificate fingerprint: you will use one or the other depending on your signing method
  • NavSip.dll registered: required for specific Azure and NAV file types; covered in the next section
  • Active OV or EV code signing certificate: issued with cloud HSM key storage

How to Configure NavSip.dll for Azure Application Signing

Certain file types — including .app and .fob files common in Azure-connected NAV deployments — require a Signature Interface Package (SIP) library to be registered before SignTool can process them. The SIP library that handles these types is NavSip.dll, distributed with Microsoft Dynamics NAV 2018.

If this step is skipped for applicable file types, SignTool returns a SIP-layer error rather than a meaningful signing failure message, which makes it difficult to diagnose. Register NavSip.dll before attempting to sign:

  1. Download Microsoft Dynamics NAV 2018 from the Microsoft Volume Licensing Service Center or MSDN.
  2. Extract the package to a local directory.
  3. Locate NavSip.dll at: Dynamics.110.NA.2468045.DVD\ServiceTier\System64Folder
  4. Copy NavSip.dll to C:\Windows\System32
  5. Register the DLL by running the following from an elevated command prompt:
regsvr32.exe C:\Windows\System32\navsip.dll

Method 1: Sign an Azure Application Using a Certificate File

This method references the certificate directly from a .crt or .cer file on disk. It is the simpler of the two methods and is appropriate for individual signing operations or workflows where the certificate file path is known and static.

SignTool Command for Azure App Signing via Certificate File

signtool.exe sign /csp "DigiCert Signing Manager KSP" /kc <keypair_alias> /f <certificate_file> /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 <file_to_be_signed>

Example

signtool.exe sign /csp "DigiCert Signing Manager KSP" /kc myapp-key-1 /f codesign.crt /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 AzureApp.exe

Key Parameters Explained

Parameter Purpose Required
/csp Specifies the KSP provider name — must match exactly as registered Yes
/kc Keypair alias — identifies the private key in DigiCert KeyLocker Yes
/f Path to the certificate file (.crt or .cer) Yes
/tr RFC 3161 timestamp server URL — ensures long-term signature validity Yes (recommended)
/fd File digest algorithm — SHA256 is the current standard; SHA1 is deprecated Yes
/td Timestamp digest algorithm — must match /fd in modern signing workflows Yes

Method 2: Sign an Azure Application Using a Certificate Thumbprint

This method reads the signing certificate from the Windows Certificate Store rather than from a file path. It is better suited to CI/CD pipelines and automated environments where certificate file paths may vary across agents, or where the certificate is centrally managed through the Windows store.

Step 1 — Sync Certificate to Windows Certificate Store

Before SignTool can locate the certificate by thumbprint, it must be present in the local Windows Certificate Store. Use the DigiCert smctl utility to sync it:

smctl windows certsync --keypair-alias=<keypair_alias>

This command fetches the certificate associated with the specified keypair alias from DigiCert KeyLocker and imports it into the Current User certificate store. Run this step on every new build agent before executing the signing command.

Step 2 — Retrieve the Certificate Thumbprint via PowerShell

$cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.FriendlyName -like "<CERTIFICATE_ALIAS>"}
$thumbprint = $cert.Thumbprint
Write-Host($thumbprint)

The -like filter matches on the certificate's friendly name, which corresponds to the keypair alias used during certsync. Copy the returned thumbprint — it will be a 40-character hexadecimal string.

Step 3 — Sign Using the Certificate Thumbprint

signtool.exe sign /sha1 <certificate_thumbprint> /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 <file_to_be_signed>

Example

signtool.exe sign /sha1 3550ffca3cd652dde30675ce681ea1e01073e647 /tr http://timestamp.digicert.com /td SHA256 /fd SHA256 AzureApp.exe

Certificate File vs. Certificate Thumbprint: Which Method Should You Use?

Both methods produce cryptographically identical signatures. The choice between them is entirely operational, based on your deployment environment and workflow architecture.

Criteria Method 1: Certificate File Method 2: Certificate Thumbprint
Setup complexity Lower — only requires a .crt file Higher — requires certsync step first
Best use case One-off signing, local developer workflow CI/CD pipelines, shared build agents
Pipeline automation Requires stable file path across agents Works without file path dependencies
Windows Store dependency None Certificate must be synced to store
Signature output Identical to Method 2 Identical to Method 1

For teams running Azure DevOps pipelines with multiple hosted agents, Method 2 is the more robust choice. The certsync step can be added as the first task in the signing stage, ensuring the certificate is always present regardless of which agent picks up the job.

How to Verify a Signed Azure Application with SignTool

Verification is not optional. A signing command that completes without error does not guarantee a valid signature — timestamp server timeouts, chain issues, and test certificate states can all produce a technically completed signing operation that fails verification. Always run verification as a post-signing step.

signtool verify /v /pa <signed_file>

Example

signtool verify /v /pa AzureApp.exe

A successful verification output will include:

  • Successfully verified: <file_path>
  • Signing Certificate Chain confirmation
  • The signature timestamp
  • Hash of file (sha256)

Common verification errors and what they indicate:

Error Code Meaning Resolution
TRUST_E_NOSIGNATURE No signature found on the file Signing command did not complete — re-run with verbose output (/debug)
CERT_E_UNTRUSTEDROOT Certificate chain does not lead to a trusted root Expected with test/self-signed certs; not an issue with CA-issued certs in production
CERT_E_EXPIRED Certificate has expired and no timestamp was applied Re-sign with a valid certificate and include /tr timestamp flag
0x800B0003 Unknown SIP error — NavSip.dll likely not registered Register NavSip.dll using regsvr32.exe as described in the prerequisites section

Common Errors When Signing Azure Apps with SignTool and KSP

After ten years of working with code signing infrastructure, these are the six errors I see most frequently in Azure signing workflows. Each one has a predictable cause and a straightforward fix.

  1. KSP provider not recognized — SignTool returns "No certificates were found that meet all the given criteria." The DigiCert KeyLocker client service is either not installed, not running, or the /csp value does not exactly match the registered KSP name. Confirm the service is running (smctl healthcheck) and that the /csp value is "DigiCert Signing Manager KSP" verbatim, including capitalization.
  2. NavSip.dll not registered — SignTool completes without error but verification fails with a SIP-layer error (0x800B0003). This happens when signing .app or .fob files without registering NavSip.dll. Register it using regsvr32.exe as described in the prerequisites section.
  3. /sha1 flag misidentified as SHA1 algorithm — Engineers avoid Method 2 because they believe /sha1 produces a weak SHA1 signature. It does not. The /sha1 flag is a certificate lookup mechanism — it tells SignTool which certificate to use from the Windows store. The hash algorithm is set by /fd SHA256.
  4. Timestamp server omitted — The signing command succeeds, the file appears signed, but the signature expires with the certificate. Any application signed without /tr will generate trust warnings after certificate expiry. Include /tr http://timestamp.digicert.com /td SHA256 in every signing command without exception.
  5. Certificate not synced to Windows store (Method 2) — SignTool returns "No certificates were found" when using the thumbprint method. The certificate has not been imported into the local store. Run smctl windows certsync --keypair-alias=<alias> before executing the sign command. In pipeline environments, add this as the first step in every signing job.
  6. Wrong keypair alias — The KSP cannot locate the private key and returns a CNG provider error. Keypair alias values are case-sensitive in DigiCert KeyLocker. Confirm the exact alias from the KeyLocker dashboard and use it verbatim in both the /kc flag (Method 1) and the certsync command (Method 2).

Expert Insight: Why Cloud KSP Signing Has Replaced USB Token Workflows in Enterprise Azure Pipelines

The shift from USB token-based code signing to cloud KSP architecture is often framed as a compliance response to the CA/B Forum's 2023 HSM mandate. That framing is technically accurate but misses the more important operational story.

USB token signing had a fundamental architectural problem in CI/CD environments: a physical token cannot be present on a cloud-hosted build agent. Teams worked around this with self-hosted agents that had tokens physically attached, or with complex token-sharing infrastructure. Both approaches created signing bottlenecks — a single physical token became a serialization point in a parallel build system. A pipeline waiting for token availability is a pipeline not scaling.

Cloud KSP removes that constraint entirely. Because the key storage is a cloud service endpoint, any authenticated build agent can perform a signing operation simultaneously, with no contention on physical hardware. For ISVs who sign thousands of artifacts per release cycle — installers, drivers, manifests, update packages — this is not a minor efficiency gain. It is an architectural prerequisite for modern release velocity.

There is also a subtler benefit: teams that integrate KSP signing into their pipeline definition files rather than post-build scripts reduce signing failures by removing manual handoff steps. When signing is a pipeline stage — not a developer task that happens after the pipeline — the audit trail is complete, the signing key access is logged, and certificate rotation does not require developer action.

Frequently Asked Questions

What is the difference between KSP and CSP in code signing?

A CSP (Cryptographic Service Provider) uses the legacy Windows CryptoAPI (CAPI) interface, which has been in place since Windows XP. A KSP (Key Storage Provider) uses the modern CNG (Cryptographic API: Next Generation) interface, introduced in Windows Vista. SignTool supports both, but KSP is required for cloud-based key stores, ECC key algorithms, and any key storage that needs to meet FIPS 140-2 Level 2 compliance. For all new Azure signing workflows, KSP is the correct choice.

Can I use Azure Key Vault instead of DigiCert KeyLocker as a KSP for SignTool?

Yes. Azure Key Vault can be used as a KSP through the Azure Key Vault CNG Provider plugin (available on GitHub). The SignTool command structure is similar — you specify the AKV provider in the /csp parameter and the key identifier in /kc — but authentication uses Azure service principal credentials rather than DigiCert KeyLocker API tokens. The choice between the two typically depends on whether your code signing certificates are issued through DigiCert (where KeyLocker is the natural fit) or whether you are managing certificates entirely within the Azure ecosystem.

Why does my SignTool command fail with "No certificates were found" when using the thumbprint method?

The certificate has not been synced to the local Windows certificate store. This is the most common cause of this error in pipeline environments. Run smctl windows certsync --keypair-alias=<alias> before executing the sign command. In Azure DevOps or GitHub Actions pipelines, add this command as the first task in the signing stage so that it runs on every agent before any signing operation executes.

Does signing with a cloud KSP slow down my build pipeline?

There is a network latency overhead per signing operation, typically one to three seconds for standard file types. For most builds, this is negligible. For pipelines signing hundreds or thousands of artifacts in a single release, DigiCert KeyLocker supports batch signing via the smctl sign command with directory-level wildcards, which reduces cumulative latency by minimizing the number of authentication round-trips. Structure batch signing jobs to group artifacts by directory rather than calling SignTool individually per file.

Is a timestamp required when signing Azure applications?

Yes, if long-term validity matters — and it always does in production deployments. Without a timestamp, the digital signature is valid only for the duration of the signing certificate. Once the certificate expires, the signature is treated as unverified by Windows trust evaluation. Timestamping embeds an RFC 3161 countersignature from a trusted Timestamp Authority (TSA) that is independent of the signing certificate's validity period. Use /tr http://timestamp.digicert.com /td SHA256 in every signing command.

Summary: Key Takeaways

For quick reference, here is what every IT administrator, ISV, and Azure engineer needs to remember about this workflow:

  • A KSP library routes SignTool signing operations through a cloud HSM, keeping the private key off local machines and in compliance with CA/B Forum Baseline Requirements.
  • Two signing methods are available: certificate file (simpler, better for local/one-off signing) and certificate thumbprint (more robust for CI/CD pipelines and shared build agents).
  • NavSip.dll registration is required for Azure NAV file types (.app, .fob) and must be completed before signing; it is not needed for standard .exe, .dll, or .msi files.
  • SHA256 is mandatory for both the file digest (/fd SHA256) and the timestamp digest (/td SHA256). The /sha1 flag in Method 2 is a certificate lookup mechanism, not a hash algorithm selector.
  • Always verify signatures after signing using signtool verify /v /pa — a completed signing command is not the same as a valid signature.
  • Timestamp every signed artifact with /tr and /td to preserve signature validity beyond certificate expiry.
  • In pipeline environments, run smctl windows certsync before every signing job to ensure the certificate is present in the Windows store.

If you need a code signing certificate compatible with cloud KSP workflows and Azure DevOps pipelines, Azure Key Vault code signing certificates provide the cloud HSM key storage required for both compliance and operational scalability. Both OV and EV options are available with DigiCert KeyLocker key storage, ready to integrate into the workflow described above.

Delivery Mode Delivery Mode

FIPS-140 Level 2 USB or Existing HSM

Secure Key Storage Secure Key Storage

Stored on an External Physical Device

Issuance Time Issuance Time

3 to 5 Business Days