Every time a user installs software, their operating system must decide whether to trust it. Code signing certificates are the mechanism that bridges that trust gap, proving the publisher's identity and guaranteeing the code has not been tampered with since it was signed.
Software supply chain attacks have become one of the most damaging categories of cybersecurity incidents. When attackers compromise a build pipeline or inject malicious code into a legitimate application, the impact cascades to every user who downloads and runs the tampered software. High-profile incidents, from the SolarWinds breach to compromised npm packages, have shown that trusting software by default is no longer viable.
Code signing addresses this problem at its root. By attaching a cryptographic signature to an executable, library, driver, or script, the developer creates a verifiable proof that the code comes from a known source and has not been modified since it was published. Operating systems, browsers, and enterprise security tools use these signatures to make trust decisions: signed code from a recognized publisher runs smoothly, while unsigned or tampered code triggers warnings or is blocked outright.
A code signing certificate is the digital certificate that makes this possible. Issued by a trusted Certificate Authority, it binds the publisher's identity to a public key and is used by signing tools to produce signatures that operating systems can verify.
The code signing process follows a straightforward three-step model: hash, sign, and verify. Here is what happens at each stage:
The signing tool computes a cryptographic hash (typically SHA-256) of the binary, script, or package. This hash is a unique fingerprint: even a single-byte change in the code will produce a completely different hash value.
The hash is encrypted with the developer's private key, producing the digital signature. The signature, along with the code signing certificate (which contains the public key and the publisher's verified identity), is embedded into the file or attached alongside it.
When the user downloads or runs the software, the operating system extracts the signature and uses the publisher's public key to decrypt the hash. It then independently hashes the downloaded file. If the two hashes match and the certificate chains back to a trusted CA, the software is verified as authentic and untampered.
If anyone modifies the code after signing, whether an attacker injecting malware or a download error corrupting the file, the hash comparison fails. The operating system then warns the user or blocks execution entirely, depending on the platform's security policy.
Code signing certificates come in two main categories, each with different validation requirements and trust levels:
The CA verifies the identity of the organization or individual requesting the certificate. On Windows, software signed with a standard certificate will initially trigger SmartScreen warnings until the publisher builds sufficient reputation through download volume. The private key can be stored in software (a PFX file) or on a hardware token, though since June 2023, CA/Browser Forum rules require hardware-based key storage for all code signing certificates.
EV certificates require a more rigorous vetting process that includes verifying the organization's legal existence, physical address, and operational status. On Windows, EV-signed software receives immediate SmartScreen reputation, meaning users see the publisher's name in the dialog instead of a warning. The private key must be stored on a FIPS 140-2 Level 2 (or higher) hardware security module or token. EV certificates are required for signing Windows kernel-mode drivers.
For organizations distributing commercial software, EV code signing is typically the preferred choice because it eliminates SmartScreen friction and signals a higher level of trust to end users. For internal tools and scripts, a standard OV certificate, or one issued by an internal CA, is often sufficient.
Code signing certificates have a finite validity period, typically one to three years. Without additional measures, all signatures produced by a certificate would become invalid the moment the certificate expires. This would force publishers to re-sign every binary every time they renew their certificate, which is impractical.
A trusted Timestamping Authority (TSA) adds a cryptographically signed timestamp to the signature at the moment of signing. This proves the code was signed while the certificate was still valid, even if the certificate later expires or is revoked.
Without timestamping, an expired certificate invalidates all its signatures retroactively. Timestamped signatures remain valid indefinitely, which is critical for software that stays in production for years, such as firmware, drivers, and long-lived enterprise applications.
Two timestamping protocols are widely used. RFC 3161 is the standard protocol supported across platforms. Microsoft Authenticode timestamping is an older, Windows-specific protocol. Most signing tools support both; best practice is to use RFC 3161 for broader compatibility.
Always timestamp every signature. It costs nothing (TSA services are free), adds no overhead to the user experience, and prevents a class of problems that is painful to fix after the fact. Many organizations make timestamping a mandatory step in their CI/CD pipeline.
Each major platform has its own code signing ecosystem with different tools, formats, and trust stores. Understanding these differences is essential for organizations that ship cross-platform software:
Microsoft's Authenticode is the most widely used code signing framework. It covers EXE, DLL, MSI, MSIX, and PowerShell scripts. The signtool.exe utility handles signing, and Windows SmartScreen uses the publisher's reputation to decide whether to warn users. Kernel-mode drivers require EV certificates and must be submitted to the Microsoft Hardware Developer Center for additional attestation signing.
Apple requires developers to sign applications with a certificate issued by Apple's own Developer ID program. Beyond signing, macOS Catalina and later require notarization, where the developer uploads the signed binary to Apple's notary service, which scans it for malware and issues a ticket. Gatekeeper then checks both the signature and the notarization ticket before allowing execution. Without notarization, macOS will block the application.
Java applications and applets are signed using the jarsigner tool with a standard code signing certificate stored in a Java KeyStore. The Java Runtime Environment verifies signatures and can enforce security policies based on the publisher's identity. This is particularly important for enterprise Java applications deployed via internal repositories.
Linux package managers (RPM, dpkg) support GPG-based signing with their own trust models. For container images, tools like Cosign (from the Sigstore project) and Docker Content Trust provide signing and verification capabilities. As container-based deployment grows, signing container images is becoming a standard part of secure CI/CD pipelines.
Code signing is a powerful trust mechanism, but it is only as strong as the practices surrounding it. Organizations face several common risks:
If an attacker steals the private key used for code signing, they can sign malware that appears to come from a legitimate publisher. This is the highest-impact risk and is why the CA/Browser Forum now mandates hardware key storage. Organizations should store signing keys in HSMs, restrict access to the signing process, and maintain audit logs of every signing operation.
When a code signing certificate expires and the signatures were not timestamped, every signed binary becomes untrusted simultaneously. For software already deployed to thousands of endpoints, this can trigger security warnings, block application launches, and create an urgent operational crisis that is difficult to resolve quickly.
When multiple developers or CI/CD pipelines can sign code without centralized oversight, there is no guarantee that only reviewed, approved code gets signed. An insider or a compromised pipeline could sign malicious or untested code. Signing should be treated as a privileged operation with approval workflows, role-based access, and complete audit trails.
Large organizations often accumulate multiple code signing certificates across different teams, geographies, and CI/CD systems, some from commercial CAs, others from internal CAs. Without a centralized lifecycle management approach, certificates expire without notice, keys are stored inconsistently, and there is no unified view of who can sign what.
Centralized certificate inventory: Evertrust CLM discovers and tracks every code signing certificate across your organization, regardless of which CA issued it or where the key is stored, giving you a single pane of glass over your entire signing infrastructure.
Policy enforcement: Define and enforce organizational rules on which teams can request code signing certificates, what key algorithms and storage mechanisms are allowed, and which approval workflows must be followed before a certificate is issued.
Automated lifecycle: Evertrust PKI automates the issuance and renewal of code signing certificates, integrating with your CI/CD pipelines to ensure signing certificates are always current and compliant, eliminating the risk of expired signatures in production.
Audit & compliance: Full audit trails of every certificate request, approval, issuance, and signing operation, helping your organization demonstrate compliance with internal security policies and external regulatory requirements.