How to Sign Software With a Code Signing Certificate

Signing is not the act of attaching a certificate to a file. The signing tool hashes the artifact, obtains a signing operation from the private key, constructs a platform-specific signature, optionally obtains trusted timestamp evidence, and embeds the resulting signature in the file format.

For a Windows PE file: the certificate identifies the public signing key, the private key produces the cryptographic signature, Authenticode stores the signature in the PE security directory, and the verifier reconstructs the signed digest before evaluating the certificate and trust chain.
SIGN
VERIFYcryptographic workflow
Artifact digesthash signed data
Private keysignature operation
CMS / signatureembedded evidence
Verifierintegrity + trust

What Actually Happens When You Sign a File?

For a typical public-key code-signing workflow, the signing tool does not encrypt the entire executable with the private key. It calculates a digest over the portions of the artifact covered by the signature, then uses the private key to produce a cryptographic signature over that digest or over a structured signature object.

The certificate is used to carry the public key and signer identity information. The verifier uses the public key from the certificate to validate the signature, recomputes the digest from the received artifact, and checks that the digest represented by the signature matches the artifact. This is why changing signed content after signing can invalidate the signature.

1. FileFinal artifact exists.
2. DigestCovered data is hashed.
3. Private keyDigest/signature structure is signed.
4. SignatureSignature data is assembled.
5. CertificatePublic key and identity accompany it.
6. VerifyVerifier recomputes and validates.
Signing operation: the private key never becomes part of the signed fileConceptual cryptographic path
Final artifactExecutable bytes are finalized before the signing boundary.
Digest functionA digest is calculated over the data covered by the platform's signature format.
Private-key operationThe signing provider performs the cryptographic operation without exposing the private key.
CertificatePublic key + signer identity + certificate extensions
VerifierUses the public key to validate the signature and evaluate trust

The Certificate Is Not the Signing Operation

A code-signing certificate contains the public key and identity information needed by a verifier. It does not give the signing tool the ability to create a signature. That capability comes from the corresponding private key.

Public evidence

The certificate binds a public key to the subject identified by the certificate and carries extensions such as key usage and extended key usage. It can be distributed with the signature.

Signing capability

The private key performs the cryptographic operation. Depending on the environment, it may be in a PFX, Windows key store/provider, HSM, smart-card-like provider, or remote signing service.

Artifact evidence

The signature binds the signer identity and public key to the signed artifact. A verifier can detect when the covered data no longer matches the signature.

Diagnostic rule: if the certificate is visible but the signing tool reports that no private key is available, installing the same public certificate again will not solve the problem. The missing object is the private-key association or the provider access to it.

Determine the Artifact and Its Signature Format

Before choosing a command, identify the actual artifact format. A Windows PE executable, a Java JAR, and a macOS application bundle do not use the same signature container or verification mechanism. The signing tool must understand the file format because it needs to place signature metadata where the platform expects it.

ArtifactSigning mechanismWhat the tool is doing
Windows EXE / DLLAuthenticode / PE signatureCreates a Windows-compatible signature associated with the PE image and certificate.
Windows MSI / packageWindows package signingSigns the package according to the package format and verification rules.
PowerShell scriptAuthenticodeAdds a script signature that PowerShell can inspect and enforce according to execution policy.
Java JARJAR signature files and signature blockCreates manifest digests, an .SF file, and a cryptographic signature block.
macOS appApple Code SigningSigns the bundle's code and associated signing data using an Apple signing identity.

Android and iOS use platform-specific application signing systems and should be treated as separate workflows rather than as another PFX-to-file signing command.

Check the Certificate's Key Usage and Private-Key Association

A certificate can be structurally valid and still be unsuitable for a signing operation. For public code signing, inspect the certificate's Extended Key Usage and Key Usage extensions, its validity dates, issuer, subject, and the presence of the corresponding private key.

PropertyWhy it matters during signing
Private key associationThe signing provider needs access to the private key corresponding to the certificate's public key.
Extended Key UsageThe certificate should be appropriate for code signing where the platform/profile requires that purpose.
Key UsageThe key must be permitted for the digital-signature operation expected by the signing environment.
Validity periodThe certificate must be valid according to the relevant signing and verification rules.
Issuer and chainThe verifier needs a trust path appropriate to the target environment.
Algorithm and key sizeThe certificate's public-key algorithm must be compatible with the signing tool and target verifier.

On Windows, Microsoft documents that SignTool can select certificates by file, subject name, issuer, or certificate hash, and that the certificate store can be searched when the private key is available through the configured cryptographic provider.

Windows EXE/DLL: Sign With SignTool and Understand the Parameters

For Windows PE files, SignTool is the most useful concrete example because its parameters expose the important pieces of the signing operation. The command below uses a password-protected PFX and requests an RFC 3161 timestamp.

signtool sign ^
  /f "C:\signing\publisher.pfx" ^
  /p "PFX_PASSWORD" ^
  /fd SHA256 ^
  /tr "TIMESTAMP_URL" ^
  /td SHA256 ^
  "C:\release\ExampleApp.exe"
OptionWhat SignTool actually uses it for
/fLoads the signing certificate from a file. For a PFX, this can provide the certificate and private key to the signing operation.
/pSupplies the password needed to open the password-protected PFX. In automation, do not expose this value in source control, command history, or build logs.
/fd SHA256Sets the file digest algorithm used when generating the signature. Current Microsoft documentation requires an explicit file digest option when signing.
/trSpecifies the RFC 3161 timestamp server endpoint.
/td SHA256Sets the digest algorithm requested for the RFC 3161 timestamp operation.
File pathIdentifies the exact artifact whose signature is being created.

Microsoft's current SignTool documentation explicitly distinguishes /fd for the file digest from /td used with /tr for the timestamp digest. The timestamp URL must be supplied separately through /tr.

Do not copy a real production password into a page example. The example deliberately uses PFX_PASSWORD and TIMESTAMP_URL.

Selecting the Certificate From the Windows Store

Using a certificate store changes certificate selection, but it does not eliminate the private-key requirement. SignTool can search the certificate store and select an appropriate certificate based on subject, issuer, certificate hash, or other selection criteria.

signtool sign ^
  /sha1 CERTIFICATE_THUMBPRINT ^
  /fd SHA256 ^
  /tr "TIMESTAMP_URL" ^
  /td SHA256 ^
  "C:\release\ExampleApp.exe"

The thumbprint is useful when several certificates have similar subjects or when automation needs deterministic selection. A production pipeline should not rely on whichever certificate happens to be selected first from a store containing multiple candidates.

For machine-level certificates, the store scope also matters. SignTool exposes options for choosing the certificate store and machine store, while the cryptographic provider controls access to the corresponding private key.

What SignTool Is Doing to the Windows File

For an Authenticode-signed PE file, the signature is not simply appended as arbitrary text. Windows has a security directory in the PE format that can point to the certificate table containing the signature information. The signing operation therefore changes the file in a format-aware way.

Hash the covered image

The signing process calculates a digest over the portions of the PE image covered by Authenticode. The signature data itself is handled separately so adding the signature does not create a circular hash dependency.

Sign with the private key

The signer creates the cryptographic signature associated with the digest and the signing certificate. The private key does not become part of the public signature data.

Store signature evidence

The resulting signature and certificate information are embedded according to the PE signing format so Windows verification tools can locate and process them.

The exact internal structure matters when diagnosing why a file verifies before a build step but fails afterward: if a later operation changes covered bytes, the verifier recomputes a different digest.

Windows PE signing anatomyWhy the signature is embedded in a format-aware location
Digest inputAuthenticode hashing covers the applicable PE image data while excluding the signature storage area that would otherwise create a circular hash dependency.
PE headersExecutable structure and metadata
Sections / image dataCode and resources covered by the signing calculation
Security directoryPoints to certificate/signature data stored with the PE
WIN_CERTIFICATEContains the Authenticode signature and certificate evidence
VerifierLocates the signature, reconstructs the covered-data digest, validates the cryptographic signature, then evaluates the certificate and trust path.

PFX/P12 Signing: What Is Actually Inside the File?

A PFX is a PKCS#12 container. In a common code-signing setup, it can carry the certificate chain and the private key protected by a password. That makes it portable, which is useful for controlled local signing but dangerous when the file is copied broadly.

PFXPKCS#12 container.
PasswordUnlocks protected contents.
CertificateProvides public key.
Private keyPerforms signing.
SignToolInvokes signing operation.
SignatureBecomes artifact evidence.

Microsoft's documentation describes the PFX signing path and specifically warns that private-key files must be protected. A PFX that contains only the public certificate is not sufficient for signing unless the corresponding private key is made available through another supported provider.

Add an RFC 3161 Timestamp as Part of the Signature Operation

A timestamp is a second cryptographic relationship layered onto the signing evidence. SignTool's /tr option requests an RFC 3161 timestamp, and /td specifies the digest algorithm requested for that timestamp operation. The TSA returns a timestamp token that the signing tool incorporates into the signature evidence.

signtool sign ^
  /f "C:\signing\publisher.pfx" ^
  /fd SHA256 ^
  /tr "TIMESTAMP_URL" ^
  /td SHA256 ^
  "C:\release\ExampleApp.exe"

File signature

Answers the cryptographic question: does the signature correspond to the signed artifact and the certificate's public key?

Timestamp token

Provides signed time evidence from the TSA for the data represented by the timestamp request.

Certificate validity

Lets the verifier evaluate the signing certificate in the context of the timestamp and the applicable revocation/trust rules.

Microsoft documents /tr as the RFC 3161 timestamp option and /td as its associated timestamp digest option.

Timestamp evidence is a second cryptographic relationshipSigning time evidence is obtained from a TSA
1. SignThe signer creates the software signature.
2. RequestA timestamp request identifies the data for which time evidence is requested.
3. TSA tokenThe TSA returns an RFC 3161 timestamp token signed by the TSA.
4. EmbedThe signing tool incorporates the timestamp evidence into the signature data.

Verify the Windows Signature at Multiple Levels

A successful signing command only proves that the signing operation completed. Verification tells you whether the resulting artifact can actually be validated under a chosen Windows policy.

signtool verify /pa /v "C:\release\ExampleApp.exe"

/pa selects the default Authenticode verification policy. /v requests verbose information, which is useful for seeing the signer and diagnostic details. Microsoft notes that SignTool's default verification behavior can otherwise use the Windows driver policy, so explicitly using /pa is important when you are testing ordinary Authenticode software.

Verification layerQuestionFailure meaning
Signature presenceCan the verifier find signature evidence?The file may be unsigned or the signature structure may be unreadable.
Digest/integrityDoes the file still produce the expected digest?The signed content may have changed.
CertificateDoes the certificate validate and identify the signer?Certificate, key, validity, or identity problem.
ChainCan the certificate chain be built to an accepted trust anchor?Chain or trust-store problem.
TimestampDoes the timestamp evidence validate?TSA, token, chain, algorithm, or embedding problem.
PolicyDoes the chosen verification policy accept it?Platform or trust-policy problem.
Verification is a sequence of gates, not one yes/no checkEach gate answers a different technical question
Signature foundCan the verifier locate usable signature evidence?
→
Digest matchesDoes the current file still match the signed data?
→
Certificate validDoes the certificate identify the expected signing key and satisfy its constraints?
→
Chain trustedCan the certificate chain reach an accepted trust anchor?
→
Policy acceptedDoes the selected Windows verification policy accept the result?

A File Can Be Cryptographically Signed but Still Fail Trust

Signature validity and trust are separate checks. A verifier can mathematically validate a signature with the public key in a certificate and still reject the certificate because its chain is not trusted, its purpose is wrong, its status is unacceptable, or the target policy does not recognize the issuing hierarchy.

SignatureCryptographic check passes.
CertificateSigner identity is inspected.
EKU/KUPurpose is checked.
ChainIssuer path is built.
TrustRoot is accepted.
PolicyPlatform accepts result.

This distinction is especially useful when a file “works on my machine.” A development machine may contain an intermediate or root certificate that is absent from another machine. That does not prove that the signed artifact itself changed.

What Happens If the Signed Artifact Changes?

The signature is tied to the data covered by the signing format. If a build or packaging operation modifies that data after signing, the verifier can recompute the digest and discover that it no longer matches the signed value.

Finalize → Sign → Verify → Release

The exact bytes that were signed are the bytes that users receive.

Finalize → Sign → Modify → Release

The release artifact can fail integrity validation because it is no longer the same signed content.

Common causes include editing executable resources, changing installer contents, rebuilding, repacking, applying a post-signing optimization, or modifying a signed script. The correct fix is usually to perform the modification before signing and sign the resulting artifact again.

PowerShell: Inspect the Certificate and Signature, Not Just the Command

PowerShell uses Authenticode for script signatures. The useful technical distinction is that the certificate selection and the script's signature status are inspectable independently.

$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert
Set-AuthenticodeSignature -FilePath .\deploy.ps1 -Certificate $cert

Get-AuthenticodeSignature .\deploy.ps1 |
  Format-List Status, StatusMessage, SignerCertificate, TimeStamperCertificate

The first command searches the current user's personal certificate store for certificates marked for code signing. The signing cmdlet applies the certificate to the script. The verification cmdlet exposes the signature status, signer certificate, and timestamp certificate information that can be used during troubleshooting.

If the script changes after signing, the signature no longer corresponds to the current script contents. Re-sign the final version instead of treating the previous signature as reusable evidence.

Java JAR Signing Is a Different Cryptographic Workflow

A signed JAR is not simply a ZIP file with a certificate attached. Java's signing model uses manifest digests, a signature file, and a signature block containing the cryptographic signature and certificate chain. jarsigner performs this packaging work and can add a timestamp using an RFC 3161 TSA.

jarsigner   -keystore signing.p12   -storetype PKCS12   -tsa TIMESTAMP_URL   app.jar   signingAlias

jarsigner -verify -verbose -certs app.jar
JAR componentTechnical role
ManifestContains digests for JAR entries that are covered by the signing process.
.SF fileContains signature-related digest information for the manifest.
Signature blockContains the cryptographic signature and certificate information for the signer.
Timestamp tokenWhen requested, provides signed time evidence associated with the JAR signature.

Oracle's current jarsigner documentation states that -tsa causes the tool to communicate with a TSA using the RFC 3161 TSP and store the returned timestamp token with the signature. Verification checks the signature and detects changes to signed entries.

macOS: Sign the Bundle, Then Verify the Bundle

Apple code signing is bundle-aware. The signing identity is associated with the Keychain, and the signing system can validate static code objects such as applications, tools, frameworks, plug-ins, and scripts. A macOS application can contain nested signed code, so signing order and bundle structure matter.

codesign --force --verbose --sign "Developer ID Application: Example Company" "Example.app"

codesign --verify --deep --strict --verbose=2 "Example.app"

The verification stage should be performed against the final application bundle. Apple's documentation describes code signing as a mechanism that allows the system to detect changes to signed code and also exposes signing information and requirements for evaluation.

Do not treat notarization as the signing command itself. Code signing establishes the application's signing evidence; notarization is a separate Apple distribution/security process.

HSM and Remote Signing Change the Key Operation, Not the Verification Model

The most important architectural difference between local, HSM-backed, and remote signing is where the private-key operation happens. The resulting software still needs a certificate, signature, timestamp where applicable, and verification.

Signer → local private key

The signing process can directly invoke the private key through the operating system or a local provider. PFX files are one common implementation, but they are not the only model.

Signer → crypto provider → HSM

The application requests a signing operation from the protected key. The private key remains inside the HSM boundary according to the HSM's capabilities and configuration.

Signer → API/service → protected key

The build system authenticates and submits a signing request. The service performs the key operation and returns signature output without exposing the production private key as a file.

This is why a PFX-based command should not simply be copied into an HSM or cloud-signing environment. The cryptographic provider interface and authorization model are different even though the resulting signature is ultimately verified with the public key.

Where the private key lives changes the signing boundaryThe verification model remains based on the resulting public signature
L

Local key

The signing host can access the private key directly through a local certificate/key provider.

Boundary: signing machine controls key access
H

HSM-backed key

The signing application requests a cryptographic operation while the private key remains within the protected hardware boundary.

Boundary: HSM controls private-key material
R

Remote key

A service authenticates the request, applies signing policy, performs the key operation, and returns signing output.

Boundary: remote service controls key access

Protect the signing key without slowing releases

For teams that need tighter control over production credentials, compare protected signing options that keep private-key operations separate from ordinary build agents.

Explore Cloud Code Signing

CI/CD: Put the Cryptographic Boundary After Testing

A secure release pipeline should treat the signing step as a controlled boundary around a finalized artifact. The pipeline builds and tests first, freezes the release candidate, invokes the signing mechanism, validates the signature and timestamp, and only then publishes the artifact.

source
  ↓
build
  ↓
test
  ↓
final artifact
  ↓
authenticated signing request
  ↓
protected private-key operation
  ↓
timestamp
  ↓
verification
  ↓
release

What should not happen

Do not store production PFX files in Git, bake private keys into container images, print PFX passwords in CI logs, or let every build agent retain a reusable production signing credential.

What the pipeline should prove

It should know which artifact was signed, which signing identity was used, whether timestamping succeeded, whether verification passed, and whether the exact verified artifact was published.

Production signing should be a controlled release gateThe exact verified artifact is the one that should be published
BuildCompile/package the release candidate.
TestFunctional and release checks.
FreezeStop changing the artifact.
SignProtected key operation.
TimestampObtain signing-time evidence.
VerifyCheck the exact output.
ReleasePublish only the verified bytes.

Diagnose Signing Failures by the Layer That Failed

Instead of treating every signing error as a certificate problem, classify the failure first.

LayerTechnical questionTypical evidence
ArtifactIs this the exact file that should be signed?Wrong path, wrong build, post-build modification.
CertificateDid the tool select the intended certificate?Subject, issuer, thumbprint, validity, EKU.
Private keyCan the provider perform the private-key operation?Missing key, inaccessible key container, provider error.
SigningWas a valid signature generated?SignTool or provider error.
TimestampWas the TSA response accepted and embedded?Timeout, token error, TSA chain error.
IntegrityDid the artifact change after signing?Invalid digest/signature after packaging.
TrustCan the certificate chain be trusted?Unknown issuer, missing intermediate, policy rejection.
PlatformDoes the target verifier accept the signature?Works on signer machine but fails on clean target.

A Reproducible Windows Signing Test

When a production pipeline fails, reduce the problem to one known artifact and one known certificate. The objective is to separate key access from timestamping and verification.

1. HashRecord the artifact hash.
2. SelectIdentify certificate thumbprint.
3. SignRun a controlled signing command.
4. VerifyUse verbose SignTool output.
5. TimestampCheck TSA evidence.
6. RecheckVerify the exact released file.

If step 3 fails, investigate certificate/private-key/provider access. If step 3 succeeds but step 4 fails, investigate the generated signature and verification policy. If the signature verifies locally but the published copy fails, compare the exact bytes of the local and published artifacts before changing certificate settings.

The Complete Technical Release Path

For a Windows desktop release, the complete path can be reduced to one chain of evidence. Every stage should preserve the relationship between the artifact, the signing identity, the private-key operation, timestamp evidence, and the published file.

ExampleApp.exe
    │
    ├── finalize build
    │
    ├── calculate signed-data digest
    │
    ├── private-key signature operation
    │
    ├── attach certificate / signature structure
    │
    ├── request RFC 3161 timestamp
    │
    ├── embed timestamp evidence
    │
    ├── SignTool verify /pa /v
    │
    ├── publish exact verified bytes
    │
    └── verify downloaded artifact again

This is the useful mental model for the page: signing is not a button that changes a file's status. It is a sequence of cryptographic and trust operations whose output must survive verification on the system that will actually consume the software.

Release Checklist With Technical Acceptance Criteria

AreaAcceptance criterion
ArtifactThe exact final release artifact is identified and will not be modified after signing.
CertificateThe selected certificate has the expected subject, issuer, validity, usage, and public key.
Private keyThe signing provider can perform the private-key operation corresponding to the certificate.
SignatureThe platform-specific verifier validates the signature and artifact integrity.
TimestampThe timestamp token is present and accepted by the target verification environment where required.
TrustThe certificate chain and applicable trust policy validate on a clean target environment.
PipelineThe published bytes are the same verified bytes produced by the signing stage.
AuditRequired signing events and release identity information are retained without exposing private key material.

Platform-Specific Next Steps

Windows / Authenticode

Continue with SignTool certificate selection, PE signing, timestamping, certificate-chain validation, and Windows trust diagnostics.

Read Windows Code Signing →

Java / JAR

Continue with keystore entries, manifest digests, signature files, signature blocks, TSA tokens, and jarsigner verification.

Read Java Code Signing →

macOS

Continue with Keychain identities, bundle signing, nested code, entitlements, requirements, and codesign verification.

Read macOS Code Signing →

Sign, inspect, verify, then release

A production signing workflow is complete only when the exact artifact users receive passes the target platform's signature, integrity, certificate, trust, and timestamp checks.

Explore Code Signing Solutions