Installing a code signing certificate is not the same as having a working code signing setup. Between receiving the hardware token or cloud HSM credentials and producing your first verified production signature, several things can go wrong silently: the certificate may be visible but the private key inaccessible, the chain may be incomplete, the timestamp server connection may fail, or the publisher name may not match what you expected.
This guide is a systematic verification checklist. Run each check in order before signing any production release. Each step includes the exact command, the expected output for a correctly installed certificate, and what to do when the output doesn’t match.
Check 1: Certificate Is Visible with Private Key Accessible
The first check confirms Windows can see the certificate and that the private key (on the token or cloud HSM) is accessible from this machine.
| # Run in PowerShell:
> Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object Subject, Issuer, NotBefore, NotAfter, HasPrivateKey, Thumbprint |
Expected output: your certificate appears in the list with HasPrivateKey showing True. The Subject field shows your organization name. NotAfter is in the future.
| What you see | What it means | Fix |
| No results returned | Certificate not in CurrentUser\My store | Confirm the CA’s setup tool completed; re-run the CA’s certificate import steps; check if the cert is in LocalMachine\My instead (run the command as Administrator) |
| Certificate listed, HasPrivateKey = False | Certificate imported but token not connected, or middleware not installed | Ensure USB token is plugged in; open SafeNet Authentication Client and confirm token is recognized; re-install middleware |
| Certificate listed, HasPrivateKey = True | Correct | Proceed to Check 2 |
Check 2: Certificate Has the Code Signing EKU
A certificate that appears in the store and has a private key can still be rejected by signtool if it lacks the Code Signing Extended Key Usage (EKU). This check confirms the EKU is present.
| # View the certificate’s enhanced key usages:
> Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -ExpandProperty EnhancedKeyUsageList
# Expected output includes: # FriendlyName ObjectId # Code Signing 1.3.6.1.5.5.7.3.3
# Alternative: use certutil to view full certificate details: > certutil -store My | findstr /i “code signing” |
Expected output: the OID 1.3.6.1.5.5.7.3.3 (Code Signing) appears in the EKU list. If you see only 1.3.6.1.5.5.7.3.1 (serverAuthentication), you have a TLS certificate installed instead of a code signing certificate.
The -CodeSigningCert filter on Get-ChildItem already screens for this OID, so if the previous check returned your certificate with that filter, the EKU is present. This check is a belt-and-suspenders confirmation and also covers cases where Get-ChildItem was run without the filter.
Check 3: Full Certificate Chain Is Trusted
signtool will reject a certificate whose chain cannot be verified up to a trusted root. This check confirms the intermediate CA and root CA are correctly installed in Windows.
| # Get your certificate’s thumbprint first:
> Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object Thumbprint, Subject
# Verify the chain using certutil (replace thumbprint with your actual value): > certutil -verify -urlfetch Cert:\CurrentUser\My\YOUR_THUMBPRINT_HERE
# Expected output ends with: # Verified Issuance Policies: None # Verified Application Policies: Code Signing # Leaf certificate revocation check passed # CertUtil: -verify command completed successfully.
# Shorter chain check without network (offline): > certutil -verify Cert:\CurrentUser\My\YOUR_THUMBPRINT_HERE |
If certutil reports a chain error, the intermediate CA certificate is not installed. Your CA’s installation guide should include the intermediate CA download. Install it by double-clicking the .crt file and placing it in the Intermediate Certification Authorities store, not the Personal store.
The -urlfetch flag tells certutil to download any missing CRL and OCSP data from the URLs embedded in the certificate. Run this version first; it catches network-level revocation check failures that the offline version misses.
Check 4: signtool Can Auto-Select the Certificate
This check confirms that signtool can locate your certificate automatically using the /a flag, which selects the best available code signing certificate. If it selects the wrong certificate when multiple are present, you will need to use /sha1 with the thumbprint instead.
| # Create a test file to sign (any .exe will do):
# Copy calc.exe from C:\Windows\System32 to a working folder as test.exe
# Run signtool with /a to auto-select and check what it selects: signtool sign /a /fd sha256 /v test.exe 2>&1
# Expected output includes a line like: # The following certificate was selected: # Issued to: Your Organization Name # Issued by: CA Name # Expires: 2026 # SHA1 hash: [your certificate thumbprint]
# If the wrong certificate is selected, pin by thumbprint: signtool sign /sha1 YOUR_THUMBPRINT /fd sha256 /v test.exe 2>&1 |
If signtool is not found, it needs to be installed via the Windows SDK. Run where signtool in Command Prompt or Get-Command signtool in PowerShell. If it returns nothing, install the Windows SDK from developer.microsoft.com or via winget install Microsoft.WindowsSDK. See the separate signtool.exe not found guide on this site for the full install path.
Check 5: Sign a Test File and Verify the Signature
The end-to-end test: sign a throwaway file and verify the signature is valid. Use a file you are willing to overwrite; the signed copy replaces the original.
| # Sign with SHA-256 digest and a timestamp server:
signtool sign /a /fd sha256 /tr http://timestamp.digicert.com /td sha256 /v test.exe
# Expected output (abbreviated): # The following certificate was selected: [your cert details] # Done Adding Additional Store # Successfully signed: test.exe
# Verify the signature: signtool verify /pa /v test.exe
# Expected output (abbreviated): # Verifying: test.exe # File is signed in Authenticode(tm) signature format. # Hash of file (sha256): [hash value] # Signing Certificate Chain: # Issued to: [Root CA name] # Issued to: [Intermediate CA name] # Issued to: [Your organization name] # The signature is time-stamped: 2026 # Timestamp Verified by: # [Timestamp authority chain] # Successfully verified: test.exe |
The critical lines to confirm: ‘Successfully signed’ during signing, ‘Successfully verified’ during verification, and ‘The signature is time-stamped’ confirming the timestamp was applied.
If the signing command succeeds but verification returns ‘The file is not digitally signed’ or ‘No signature found,’ the file may have been opened by another process between signing and verification. Try on a different copy of the file. If signtool sign reports success but verify consistently fails, the chain is incomplete or the certificate has an issue not caught by earlier checks.
Check 6: Timestamp Is Present and Valid
A signature without a timestamp expires when the certificate expires. This check confirms the timestamp was successfully embedded. The verify output from Check 5 includes timestamp information, but this command extracts it explicitly.
| # Check timestamp details specifically:
signtool verify /pa /v test.exe 2>&1 | findstr /i “timestamp time-stamp”
# Expected output includes both lines: # The signature is time-stamped: [weekday], 2026 [time] # Timestamp Verified by:
# If no timestamp lines appear, re-sign with the /tr flag explicitly: signtool sign /sha1 YOUR_THUMBPRINT /fd sha256 /tr http://timestamp.digicert.com /td sha256 /v test.exe
# Alternative timestamp servers if DigiCert is unreachable: # http://timestamp.sectigo.com # http://timestamp.globalsign.com/scripts/timestamp.dll # http://tsa.starfieldtech.com |
Check 7: Publisher Name Appears Correctly in File Properties
The publisher name users and Windows see in UAC dialogs and file properties comes from the certificate’s Subject field. Verify it shows exactly what you intend before distributing any signed software.
Right-click the signed test.exe and select Properties. Go to the Digital Signatures tab. Click the listed signature and select Details. The Signer information field shows the name as it will appear in UAC dialogs. Confirm it reads your organization name as expected.
In PowerShell:
| # View the signer name from the file’s embedded signature:
> Get-AuthenticodeSignature test.exe | Select-Object -ExpandProperty SignerCertificate | Select-Object Subject, Issuer
# Expected Subject format for OV: # CN=Your Organization, O=Your Organization, C=US
# Expected Subject format for EV adds jurisdiction fields: # CN=Your Organization, O=Your Organization, L=City, # S=State, C=US, OID.2.5.4.15=Private Organization, # OID.1.3.6.1.4.1.311.60.2.1.3=US
# The O= (Organization) value is what appears as publisher name in UAC. |
Check 8 (Cloud HSM): Verify Cloud Signing Credentials
If you are using a cloud HSM signing service rather than a physical token, the equivalent checks involve confirming API credentials work and test signing succeeds through the service.
DigiCert KeyLocker (smctl)
| # Verify smctl can authenticate and list available certificates:
smctl windows certsync # Expected: certificates appear in the Windows certificate store
smctl sign –fingerprint YOUR_CERT_FINGERPRINT –input test.exe # Expected: signing completes without authentication error |
SSL.com eSigner (CodeSignTool)
| # Test authentication and signing:
CodeSignTool sign -username=YOUR_EMAIL -password=YOUR_PASSWORD -credential_id=YOUR_CREDENTIAL_ID -totp_secret=YOUR_TOTP -input_file_path=test.exe -output_dir_path=./signed/ # Expected: signed file appears in ./signed/ directory |
Verification Checklist at a Glance
| Check | Command | Pass condition |
| 1. Certificate visible with key | Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | HasPrivateKey = True |
| 2. Code Signing EKU present | Get-ChildItem … | Select-Object -ExpandProperty EnhancedKeyUsageList | OID 1.3.6.1.5.5.7.3.3 listed |
| 3. Chain trusted | certutil -verify -urlfetch Cert:\CurrentUser\My\THUMBPRINT | CertUtil: -verify command completed successfully |
| 4. signtool selects cert | signtool sign /a /fd sha256 /v test.exe | Your org name in ‘Issued to’ |
| 5. Sign and verify | signtool sign… then signtool verify /pa /v test.exe | Successfully verified: test.exe |
| 6. Timestamp present | signtool verify /pa /v test.exe | findstr timestamp | The signature is time-stamped: 2026 |
| 7. Publisher name correct | Get-AuthenticodeSignature | select SignerCertificate | O= field shows expected org name |
Frequently Asked Questions
The certificate appears with HasPrivateKey = True but signtool says ‘No certificates were found’
This usually means signtool is running in a context that does not have access to the certificate store where the token’s key is registered. Common causes: signtool is running in a 32-bit process on a 64-bit machine and the certificate is in the 64-bit store (or vice versa); signtool is running under a different user account in a CI/CD context and the certificate is only in the current user’s store; the token middleware is not running or needs a PIN entry to make the key available. Run signtool from the same PowerShell session where Get-ChildItem confirmed the certificate, and ensure the token PIN has been entered in SafeNet Authentication Client for that session.
certutil -verify reports ‘Revocation check failed’
Revocation check failure usually means the machine cannot reach the CRL distribution point or OCSP endpoint URLs embedded in the certificate. These checks require internet access to the CA’s infrastructure. On a machine behind a corporate firewall or proxy, these endpoints may be blocked. Confirm the machine has outbound HTTPS access to the CA’s revocation infrastructure. If revocation checks must work behind a proxy, configure the WinHTTP proxy settings (netsh winhttp set proxy) so certutil can reach the revocation endpoints. For offline environments, revocation checking will consistently fail; the signing process still works but the certificate’s revocation status cannot be confirmed in that environment.
The signature verifies successfully but the UAC dialog shows ‘Unknown Publisher’
‘Unknown Publisher’ in UAC indicates the certificate’s issuing CA is not in the Trusted Publishers store for that machine, or the chain cannot be verified to a trusted root at UAC verification time. This is distinct from signtool verify succeeding: signtool verify checks the signature technically; UAC applies additional trust policy. Ensure the root CA certificate is in the Trusted Root Certification Authorities store and the CA is in the Windows root program. For internal CA certificates, the CA must be explicitly deployed to machines via Group Policy or manual import into Trusted Root. For publicly issued OV/EV certificates from a CA in Microsoft’s root program, UAC should show the publisher name automatically without additional steps.

Gloria Bradford is a renowned expert in the field of encryption, widely recognized for her pioneering work in safeguarding digital information and communication. With a career spanning over two decades, she has played a pivotal role in shaping the landscape of cybersecurity and data protection.
Throughout her illustrious career, Gloria has occupied key roles in both private industry and government agencies. Her expertise has been instrumental in developing state-of-the-art encryption and code signing technologies that have fortified digital fortresses against the relentless tide of cyber threats.