A code signing certificate, also known as a Software Publisher Certificate (SPC), ensures that binaries that are distributed are from a known and trusted source and have not been tampered with.

Self-Signed Code Signing Certificate[edit | edit source]

The following was done inside the Developer Command Prompt from Visual Studio. The utilities used in this section are makecert, signtool, and pvk2pfx.

Use the makecert utility to generate a new certificate authority, and then a SPC based on this CA. In both cases, you have the option to specify a password for the private key.

## Options used by makecert are:
## -r  = self signed
## -pe = private key is exportable
## -n  = subject's certificate name
## -a  = signature algorithm
## -cy = certificate type. authority being a CA, end being end-entity
## -sky = subject's key type. Signature, used for digital signature.
## -sv = Subject's pvk private key file
## -ic = Issuer's certificate
## -iv = Issuer's pvk private key

## Generate a CA, issued to "Self Signed CA"
$ makecert -r -pe -n "CN=Self Signed CA" -ss CA -a sha256 -cy authority -sky signature -sv CA.pvk CA.cer

## Generate a SPC with this CA, issued to "Leo Leung"
$ makecert -pe -n "CN=Leo Leung" -a sha256 -cy end -sky signature -ic CA.cer -iv CA.pvk -sv SPC.pvk SPC.cer

You should have a private key and a certificate file for both the CA and code signing certificate.

To sign your code, convert the PVK private key file into a PFX file.

$ pvk2pfx -pvk SPC.pvk -spc SPC.cer -pfx SPC.pfx

Sign the code using signtool. You can sign and timestamp all in one step. Alternatively, you can use signtool timestamp to add or update the timestamp countersignature after signing.

## Options
## /f = The pfx certificate and private key file
## /fd = The signing algorithm. If not specified, SHA1 will be used
## /tr = Timestamping server
## /td = Timestamping algorithm
$ signtool sign /v /f SPC.pfx /fd sha256 /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td sha256 putty.exe
Use SHA256
SHA-1 is deprecated and all code signing should be done with SHA256. This includes the timestamp countersignature.

The timestamping URL should point to a timestamping service that allows for the certificate's timestamp to be authenticated. This is done by adding an extra timestamp countersignature to the signature. See the #Timestamping Services section for other options and information.

Timestamping Services[edit | edit source]

SHA-1, RFC 3161 timestamping URLs:

SHA-256, RFC 3161 timestamping URLs:

Without timestamping, the certificate's signature is verified using the current system time, which may be past the certificate's validity period, rendering the signature as invalid if the certificate has expired.

With timestamping however, the certificate's signature will be verified at the time of signing as specified by the timestamp service. Regardless of whether the certificate has expired at the time of verification, the signature will still be valid.

See Also[edit | edit source]