1 Fundamentals
1.1 Definition and purpose
Code signing is the practice of attaching a cryptographic signature to software or related executable content. The signature is created with a private key associated with a certificate, allowing recipients to check who produced the code and whether it has changed after signing. It is used for programs, scripts, drivers, firmware, and packaged applications.
The main purpose of code signing is to establish trust during download, installation, or execution. Operating systems, application stores, and distribution platforms often use it as one input in deciding whether to warn the user, allow execution, or apply additional checks.
1.2 Core security goals
Code signing is designed to support several related security objectives. These include identifying the publisher, detecting post-signing modifications, and providing signals that influence trust decisions in software distribution.
1.2.1 Authentication of the publisher
A signature can indicate which certificate holder signed the code. When the certificate is issued by a trusted authority and the chain validates correctly, the recipient gains some assurance about the identity of the publisher.
1.2.2 Integrity verification
If the signed file is altered after signing, verification usually fails. This helps detect tampering, corruption, or substitution, since the hash used during signing will no longer match the file’s current contents.
1.2.3 Trust and reputation signals
Signed code often receives different treatment from unsigned code. Software platforms may use the presence of a valid signature, certificate history, or publisher reputation as part of a broader trust model. These signals can reduce user uncertainty, although they do not guarantee that the software is safe.
1.3 Relationship to digital signatures
Code signing is a specialized use of digital signatures. A digital signature is a general cryptographic method for proving that data was signed by a holder of a private key and has not been modified. Code signing applies that method to executable software and often adds software-specific policies, certificate validation rules, and metadata.
2 Technical process
2.1 Signing workflow
The signing process usually begins after a program or package has been built. The file is hashed, the hash is signed with a private key, and the resulting signature is attached to the file or stored alongside it in a platform-specific format.
2.1.1 Hash generation
A cryptographic hash function produces a fixed-length digest of the code. Even a small change in the file typically produces a very different digest, which makes the hash suitable for change detection.
2.1.2 Signature creation
The digest is encrypted or otherwise processed with the signer’s private key to create the digital signature. Only the key holder should be able to generate a valid signature for that certificate.
2.1.3 Certificate attachment
The signature is packaged with the signed file or stored in a related metadata structure. Many systems also include certificate information, so that verification can locate the public key needed to check the signature.
2.2 Signature verification
Verification occurs when a system or user agent checks whether the signature is valid and whether the signer can be trusted under current policy. This may happen at install time, launch time, or during package validation.
2.2.1 Certificate chain validation
The verifier checks whether the signer’s certificate chains to a trusted root through one or more intermediate certificates. This process helps determine whether the certificate was issued by a recognized authority.
2.2.2 Signature and hash comparison
The file is hashed again, and the result is compared against the signed digest using the public key from the certificate. A match indicates that the file has not been changed since signing and that the signature was created with the corresponding private key.
2.2.3 Timestamp checking
A timestamp can show when the code was signed. This is useful when certificates expire, because a valid timestamp may allow older signed code to remain trusted if it was signed before expiration and the verification policy permits it.
2.3 Certificates and key management
Code signing depends on careful handling of cryptographic keys and certificates. If the private key is exposed or the certificate is mismanaged, the trust value of the signature can be weakened or lost.
2.3.1 Private key protection
The private key must be stored securely, often in hardware security modules, smart cards, protected servers, or similarly controlled environments. Strong access controls are important because anyone with the private key can produce signatures that appear legitimate.
2.3.2 Public key distribution
The public key is usually distributed through the certificate and the surrounding trust infrastructure. Verifiers rely on trusted certificate authorities, embedded trust stores, or repository metadata to obtain the correct public key information.
2.3.3 Certificate expiration and renewal
Certificates have limited lifetimes. Organizations renew them to maintain continuity in signing operations, and they may re-sign software when certificates change. Expiration does not necessarily invalidate already distributed code if timestamping and policy rules allow continued verification.
3 Types of code signing
3.1 Application signing
Application signing is used for desktop and server programs distributed as installers, bundles, or standalone binaries. It helps users verify the publisher and can reduce warning messages during installation or first launch.
3.2 Driver signing
Driver signing is commonly required for low-level software that interacts directly with hardware or the operating system. Because drivers can affect system stability and security, signature checks are often enforced more strictly than for ordinary applications.
3.3 Script signing
Scripts may be signed to confirm who authored them and to discourage unauthorized editing. This is especially useful in administrative environments where automated scripts are used for configuration or maintenance.
3.4 Firmware signing
Firmware signing protects code that runs on embedded devices, controllers, or hardware components. Verification at boot or update time helps ensure that only approved firmware is installed.
3.5 Mobile app signing
Mobile platforms generally require app signatures before installation or distribution. The signature identifies the developer and supports platform rules for update continuity, package acceptance, and execution permissions.
4 Infrastructure and standards
4.1 Certificate authorities
Certificate authorities issue certificates that bind a public key to an identity. In code signing, these authorities help establish a chain of trust that verifiers can evaluate against their trusted roots.
4.2 Public key infrastructure
Public key infrastructure provides the rules, services, and administrative processes for issuing, managing, revoking, and validating certificates. Code signing relies on this framework to make signature verification practical at scale.
4.3 Timestamping services
Timestamping services add an independent record of when a signature was created. They are often used to preserve trust in signed code after a certificate expires or is later replaced.
4.4 Common file and signature formats
Code signing is implemented through several file and metadata formats, each tailored to a platform or distribution system. These formats define how signatures are stored and how verification tools locate them.
4.4.1 Authenticode
Authenticode is a Microsoft signing format used for Windows software and related executables. It supports embedded signatures and integrates with Windows trust and policy mechanisms.
4.4.2 JAR signing
JAR signing is used for Java archive files. It allows tools and runtime environments to verify the source and integrity of packaged Java content.
4.4.3 APK and mobile package signing
Mobile package formats such as APK include signing structures that support application verification on mobile operating systems. These signatures are central to app installation, updating, and platform enforcement.
4.4.4 Package repository signatures
Software repositories may sign packages, release metadata, or repository indexes. This helps users and package managers confirm that retrieved files came from the intended distribution channel.
5 Implementation and platforms
5.1 Desktop operating systems
Desktop systems typically integrate code signing into application launch controls, installer validation, and system component policy. The exact behavior depends on the platform and the type of file being verified.
5.1.1 Windows
Windows uses code signing extensively for applications, drivers, scripts, and system components. Verification may affect installation prompts, execution warnings, SmartScreen-style reputation checks, and kernel-mode enforcement.
5.1.2 macOS
macOS uses signature validation to support application identity checks and platform security features. Signed code may also be associated with developer certificates, notarization workflows, and quarantine handling.
5.1.3 Linux distributions
Linux distributions often emphasize package signing and repository trust rather than signing every executable individually. Package managers verify repository metadata and package signatures before installation or upgrades.
5.2 Mobile ecosystems
Mobile ecosystems rely heavily on signing because app installation is tightly controlled by the platform. The signature links the app to its developer account and supports update and integrity checks.
5.2.1 Android
Android applications are signed before distribution, and the signature is used to identify the developer and validate updates. Package managers and platform services depend on the signature during installation and replacement.
5.2.2 iOS
iOS uses signing as part of its app distribution and execution model. Signing helps enforce that apps come from approved sources and are associated with valid developer credentials.
5.3 Embedded and hardware devices
Embedded systems often require signed firmware to protect boot chains, device updates, and recovery images. This is important where physical access or remote update mechanisms could otherwise be abused to load unauthorized code.
6 Security considerations
6.1 Malware prevention
Code signing can reduce certain forms of malware distribution by making it easier to identify the source of software and by enabling platform enforcement. However, a valid signature does not by itself prove that software is benign.
6.2 Key theft and certificate abuse
If attackers steal signing keys or gain unauthorized access to signing systems, they may produce code that appears authentic. This makes key protection, access logging, and incident response critical to the overall security model.
6.3 Revocation mechanisms
Revocation systems allow certificates to be marked as no longer trusted before their natural expiration. Verification tools may consult revocation lists or online status services, although the extent and timing of checking can vary by platform.
6.4 Trust store management
Trust stores contain the root certificates that verifiers accept as anchors of trust. Managing these stores carefully is important, because adding or removing trusted roots changes which signatures are accepted.
6.5 Limitations of code signing
Code signing does not inspect program behavior, detect all vulnerabilities, or guarantee ongoing trustworthiness. A signed application can still contain bugs, be misconfigured, or perform unwanted actions, and some threats arise after signing or through compromised build systems.
7 Deployment and distribution
7.1 Build pipelines and release automation
Modern software development often integrates signing into automated release pipelines. After a successful build and validation stage, artifacts may be signed automatically before being published to users or repositories.
7.2 Update systems
Update systems use code signing to confirm that patches and new versions originate from the expected publisher. This helps prevent malicious update substitution and supports secure upgrade paths.
7.3 Third-party software repositories
Repositories that host software from many publishers often require package signatures or repository metadata signatures. This adds a layer of assurance for users who obtain software through package managers or curated catalogs.
7.4 Enterprise software distribution
Organizations frequently use code signing in internal deployment tools, software catalogs, and managed update systems. Signed code can help administrators enforce trusted software policies across fleets of devices.
8 Best practices
8.1 Secure key storage
Private keys should be protected with strong technical and procedural controls. Hardware-backed storage, limited operator access, and audited signing requests are common safeguards.
8.2 Separation of build and signing environments
Many organizations keep build systems separate from signing systems. This reduces the chance that a compromise of the build environment will expose signing keys or allow unauthorized release signing.
8.3 Reproducible and auditable builds
Reproducible builds make it easier to confirm that a signed artifact matches a known source state. Audit logs and release records also help trace what was signed, when it was signed, and by whom.
8.4 Regular certificate lifecycle management
Certificates should be monitored for expiration, renewal, revocation status, and policy changes. Good lifecycle management prevents interruptions in distribution and reduces the risk of using outdated credentials.
9 History and evolution
9.1 Early software trust models
Early software distribution often depended on physical media, trusted vendors, or manual verification. Trust was based more on the distribution channel than on cryptographic proof.
9.2 Growth of internet-based software distribution
As software moved online, verifying origin and integrity became more important. Code signing emerged as a practical way to support trust when files could be copied, mirrored, or altered in transit.
9.3 Modern signing requirements
Contemporary platforms often require signatures for applications, drivers, and packages. These requirements reflect the need for automated trust decisions in large-scale distribution systems and managed devices.
9.4 Emerging approaches and automation
Recent developments include stronger automation, hardware-backed key protection, and tighter integration with build and deployment tools. Some systems also combine signing with additional checks such as reputation services, attestations, and policy-driven release controls.