What is Code Signing?

Topics DevSecOps Code Signing

Definition

Code signing is a cryptographic process that uses a digital signature to confirm a software artifact’s origin and integrity. It ensures the code hasn’t been altered and allows systems to verify the publisher at install and runtime. With certificates from trusted Certificate Authorities (CAs), code signing supports both security and regulatory compliance across deployment environments.

Overview of Code Signing

Code signing protects software by verifying its origin and integrity before it reaches users. As supply chain attacks increase, signing code with a cryptographic signature helps prevent tampering and impersonation. It builds trust, stops unauthorized software, and is essential for securing today’s development and distribution pipelines.

Benefits of Code Signing

The key benefits of code signing include:

Ensuring Integrity and Authenticity: Unsigned or modified code is often blocked or flagged by modern operating systems like Windows and macOS.

Building User Trust: Signed software avoids warnings and improves installation flow, especially important in enterprise and mobile app environments.

Protecting Against Malware: Code signing helps defend against supply chain attacks by detecting tampering and preventing unauthorized code execution.

How Code Signing Works

Code signing involves a series of cryptographic steps that verify the identity of the software publisher and ensure the integrity of the code. The process can be broken down into three main stages: generating a certificate, signing the code, and verifying it at runtime.

Generating a Certificate

The process begins when a developer or organization requests a code signing certificate from a trusted Certificate Authority (CA), which verifies their identity. After approval, the CA issues a digital certificate containing the organization’s name, public key, and metadata. The developer also generates a private/public key pair, with the private key kept secure and the public key embedded in the certificate.

Signing and Verification Process

  1. Hashing the Code: Before signing, a cryptographic hash (e.g., SHA-256) of the software file is generated. This hash serves as a unique fingerprint of the file’s contents.
  2. Creating the Digital Signature: The hash is then encrypted using the developer’s private key, producing the digital signature. This signature ensures that any changes to the file after signing will invalidate the hash comparison.
  3. Attaching the Certificate and Signature: The digital signature and the code signing certificate are embedded into the software package. Optionally, a timestamp can also be added to confirm when the code was signed.
  4. Runtime Verification: When the signed software is run or installed, the operating system or platform uses the public key (extracted from the certificate) to decrypt the signature and recompute the hash of the file. If the hashes match, it confirms that the file has not been altered and that it originated from the verified publisher.

This process ensures that tampered or unverified software cannot be executed without triggering security warnings or being blocked entirely.

Cryptographic Standards

Several industry-standard algorithms and formats support this process:

  • SHA-256: A widely used cryptographic hash function that generates a fixed-length hash from the code. It is collision-resistant and helps ensure data integrity.
  • RSA / ECDSA: Public-key algorithms used for signing. RSA is more commonly used but larger in key size, while ECDSA offers a lightweight alternative with comparable security at lower computational cost.
  • X.509: The standard format for public key certificates. It defines the structure of the certificate and includes fields such as subject name, issuer name, public key, serial number, and validity period.

Together, these elements provide a robust and verifiable trust framework that underpins secure software distribution across platforms and devices.

The Role of Digital Signatures

At the heart of code signing lies the digital signature – a cryptographic assurance that software is authentic and unaltered. These signatures are generated using asymmetric cryptography, a technique that employs a pair of mathematically linked keys: a private key known only to the signer, and a public key that anyone can use to verify the signature.

Key Benefits

Digital signatures provide three core security guarantees:

  • Authenticity: Confirms the code was signed by the claimed publisher.
  • Integrity: Ensures the code hasn’t been altered since it was signed.
  • Non-repudiation: Prevents the signer from denying authorship.

Together, these properties form the foundation of trust in the software supply chain. When issued by a trusted Certificate Authority (CA), digital signatures add third-party validation—supporting both security and compliance in regulated industries like finance and healthcare.

As software moves rapidly through CI/CD pipelines and attackers increasingly target development workflows, code signing is essential—not just for verification, but as a core defense against tampering, impersonation, and insider threats.

Key Components

  • Code Signing Certificate – from a Certificate Authority
  • Private Key – used to sign
  • Public Key – used to verify
  • Timestamp – ensures signature remains valid after certificate expiration

The Role of Timestamps in Code Signing

Timestamping is a foundational aspect of resilient code signing. It ensures that signed code remains trusted—even after the signing certificate expires—by adding a cryptographic timestamp at the moment of signing.

Here’s how it works:

  1. During the signing process, the signing client sends a request to a trusted timestamp server (TSA), which returns a timestamp token that includes the time, hash, and signature.
  2. This token is embedded into the signed file alongside the digital signature.
  3. When the code is verified later—especially after the certificate has expired—systems check that the timestamp was issued by a trusted source and was applied while the certificate was still valid.

This practice preserves the long-term validity of your code, simplifies compliance audits, and ensures continued functionality across systems. Platforms like JFrog provide built-in timestamping services as part of the signing workflow, making it easy to implement without additional infrastructure.

Code Signing Pitfalls to Avoid

Even mature teams can overlook critical details in code signing. Avoid these common mistakes that weaken security or disrupt workflows:

Skipping Timestamping: A signed artifact without a timestamp will become invalid once the certificate expires. This can break applications or create unnecessary trust barriers during installation. Always configure your signing tools to use a trusted timestamping service.

Using Self-Signed Certificates: While self-signed certificates may be acceptable in internal testing environments, they are not trusted by operating systems, browsers, or mobile platforms. Production code should always be signed with certificates issued by a reputable CA.

Neglecting Revocation Protocols: If you’re not prepared to revoke certificates quickly, you’re leaving a major gap in your incident response plan. Define clear procedures for revocation and validate that they work in practice.

Treating Signing as a One-Time Task: Signing should not be an afterthought or manual step at the end of development. Integrate it into your CI/CD pipelines and automate verification checks to ensure consistent, secure delivery across releases.

Code Signing vs. Other Security Tools

While code signing is a vital security control, it is important to understand how it fits within a broader software assurance strategy:

  • Checksums and Hashes – Hashes (e.g., SHA-256) can verify the integrity of files by detecting changes—but they cannot confirm who created the file or if it was ever signed. They are often used in tandem with signing but do not offer authentication.
  • Encryption – Encryption ensures that data is only accessible to authorized parties by transforming it into unreadable ciphertext. However, encryption alone does not verify software authenticity or guard against tampering once decrypted.
  • Container Signing – In DevOps environments, signing container images adds integrity and origin verification for packaged applications. Tools like Cosign and Notary support this. Container signing complements code signing by extending trust into deployment artifacts.

Each of these tools addresses a different layer of the security model. Code signing specifically addresses trust and integrity in the software’s origin and lifecycle, serving as a cornerstone for secure software distribution.

Code Signing in Different Environments

Code signing plays a vital role across development, mobile, and enterprise environments, with each having its own unique requirements:

Software Development: In CI/CD workflows, code signing validates every build before release, preventing tampered artifacts from reaching users.

Mobile Applications: Platforms like iOS and Android require apps to be signed before they can be published or installed, rejecting unsigned apps to protect users from malicious code.

Enterprise Environments: Within organizations—especially in finance, healthcare, and critical infrastructure—code signing enforces internal trust policies. It ensures that only authorized scripts, installers, and updates run across endpoints.

Across all platforms, code signing provides a consistent way to verify software origin and integrity—whether it’s public-facing or internal.

Best Practices for Code Signing

Implementing code signing effectively goes beyond simply applying a digital signature. To ensure software security, trust, and compliance at scale, organizations must adopt a set of best practices across the lifecycle of certificate management, signing operations, and incident response.

Choosing the Right Certificate

Selecting the appropriate type of code signing certificate depends on your organizational needs, risk profile, and deployment targets:

Standard Code Signing Certificates are commonly used by individual developers and smaller organizations to sign applications and scripts. While these certificates establish publisher identity, they undergo basic verification by the Certificate Authority (CA) and may not satisfy stricter system or enterprise security policies.

Extended Validation (EV) Code Signing Certificates undergo a rigorous identity verification process by the CA, making them a requirement for signing Windows kernel-mode drivers and often preferred in high-security environments. EV certificates offer higher trust levels and may help avoid installation warnings or SmartScreen filter blocks on Windows systems.

In regulated industries or enterprise software distribution, EV certificates are considered a baseline for secure code delivery. Many organizations also use dedicated certificates for different products or teams to segment risk and streamline revocation procedures if needed.

Key Management

The private key used in code signing is a critical security asset. If compromised, attackers could use it to distribute malware disguised as trusted software. As such, strict key management is non-negotiable:

Hardware Security Modules (HSMs): Store private keys in tamper-resistant hardware or use cloud-based HSMs to prevent unauthorized access. These devices provide FIPS 140-2 or Common Criteria-certified environments and integrate with modern CI/CD tools.

Secure Cloud Vaults: For cloud-native workflows, key management services (e.g., AWS KMS, Azure Key Vault) can isolate and control key usage through access policies and audit logs.

Role-Based Access Control (RBAC): Only authorized personnel should be able to initiate signing operations. RBAC ensures that signing keys are not accessible to developers who don’t need them and reduces insider threat exposure.

Never Store Keys in Plaintext: Storing private keys on developer workstations or in unsecured repositories creates a major attack vector. Always enforce secure access protocols and centralized control.

By implementing these controls, organizations can prevent key leakage, reduce insider risk, and ensure that only trusted personnel or services can sign production code.

Renew and Revoke

Proper lifecycle management of signing certificates helps ensure long-term trust and minimizes the impact of compromise or expiration:

Renew Certificates Proactively: Plan renewals well in advance to prevent service disruption. Automate renewal tracking and ensure that signing workflows are updated with the new certificate.

Use Timestamping: Even after a certificate expires, timestamped signatures remain valid as long as the code hasn’t been altered. This preserves trust in previously released artifacts.

Revoke Immediately Upon Compromise: If there is any suspicion that a private key has been exposed, revoke the certificate without delay. Use Certificate Revocation Lists (CRLs) or the Online Certificate Status Protocol (OCSP) to notify relying parties and block malicious reuse.

The Future of Code Signing

Code signing is evolving to meet new challenges in security, compliance, and cryptography:

Post-Quantum Cryptography: Current algorithms like RSA and ECDSA won’t withstand future quantum attacks. Standards bodies like NIST are preparing quantum-resistant alternatives to future-proof digital signatures.

DevSecOps Integration: Signing is becoming a built-in part of CI/CD, with automation and policy-as-code enabling fast, secure releases without manual intervention.

Regulatory Shifts: New laws and standards—from SBOM mandates to audit traceability—are raising the bar for software trust and provenance. Code signing is central to meeting these demands.

As threats grow and standards emerge, code signing is becoming not just a best practice—but a baseline for software application assurance.

Managing Code Signing with JFrog

Code signing is essential for securing the software supply chain, ensuring code authenticity, integrity, and regulatory compliance. As threats increasingly target the build and release process, JFrog embeds code signing into the CI/CD pipeline to protect every stage of development without sacrificing speed. Its platform offers automated signing, secure private key management, customizable policy enforcement, and deep integration with JFrog Xray to detect unsigned or altered artifacts—enabling scalable, compliant, and tamper-resistant software delivery. For more information, please visit our website, take a virtual tour, or set up a one-on-one demo at your convenience.

Release Fast Or Die