signtool sign: Authenticode Code Signing in CI
signtool sign attaches an Authenticode signature to a binary; in CI you pass /fd for the file digest and /tr plus /td to add an RFC 3161 timestamp so the signature outlives the cert.
signtool ships with the Windows SDK. The modern recipe uses SHA-256 file digests and an RFC 3161 timestamp server so signed binaries stay valid after the signing certificate expires.
What it does
signtool sign signs one or more files with a certificate from a store, PFX, or by subject name, and (with /tr) countersigns with a trusted timestamp authority. /fd sets the file digest algorithm and /td the timestamp digest; both should be sha256.
Common usage
:: sign with a PFX and RFC 3161 timestamp
signtool sign /f cert.pfx /p %CERT_PASSWORD% ^
/fd sha256 ^
/tr http://timestamp.digicert.com /td sha256 ^
/d "My App" app.exe
:: sign using a cert already in the store, by subject name
signtool sign /a /n "Acme Corp" /fd sha256 ^
/tr http://timestamp.digicert.com /td sha256 app.exe
:: verify
signtool verify /pa /v app.exeOptions
| Flag | What it does |
|---|---|
| /f <pfx> | Sign with a PFX/PKCS#12 file |
| /p <password> | Password for the PFX |
| /fd <algo> | File digest algorithm (use sha256) |
| /tr <url> | RFC 3161 timestamp server URL |
| /td <algo> | Timestamp digest algorithm (use sha256) |
| /a | Auto-select the best signing cert from the store |
| /n <name> | Select a store cert by subject name |
In CI
Always timestamp with /tr (RFC 3161), not the older /t (Authenticode), so the signature remains valid after the cert expires. Pass the PFX password from a secret, never inline. For EV/HSM certs the key lives in a token, so use /n or /sha1 to select it rather than /f.
Common errors in CI
"SignTool Error: No certificates were found that met all the given criteria" means /n /a or /sha1 matched nothing in the store, or the PFX was not imported; verify the cert is present and not expired. "The specified timestamp server either could not be reached or returned an invalid response" is a flaky or blocked /tr URL; retry or use a second TSA. "SignTool Error: ISignedCode::Sign returned error: 0x80092004" usually means the private key is missing or inaccessible (common with HSM/EV tokens in a non-interactive session).