Let’s define Code signing in brief.
Code signing is a method of putting a digital signature on a file, document, software, or executable to test its authenticity and genuineness in regards to the functionality and features that it provides. This also ensures that the software entity (file, document, software, or executable) is not tampered with while in transit.
Code signing can be implemented in two ways: Client-side signing & Server-side signing.
Both mentioned Code signing methods that were popular until the SolarWinds’ attack came into the limelight and post that Client-side signing became the talk of the town as this doesn’t require to upload/move the signing files, hence preventing the attacks where malicious code is also getting signed as part of the original file/entity signing.
Time to understand the hashing function first:
The hashing algorithm is the cryptographic function that generates a fixed-length output that is called digest or hash value from a given input that may be of arbitrary size. The hash function has a property to generate a unique and one-way/non-reversible output which means we can’t get to the original input value by doing a reverse hash operation.
Let’s look at a hashing algorithm example with a simple hash function:

In the example above, a cryptographic hash function SHA-256 is shown that converts the arbitrary data into a fixed-size 256-bit hash value.
Client-side hashing, defined: computing the file’s hash locally, on the developer’s machine or build server, and sending only that hash (not the file itself) to the signing service for signing, so the full artifact and, more importantly, the private key never need to interact directly over a network connection.
Key Takeaways
- The choice isn’t about hashing security, SHA-256 is SHA-256 either way, it’s about what has to leave the build environment: the full artifact (server-side) or just its hash (client-side).
- Client-side hashing reduces bandwidth for large artifacts and narrows the attack surface, since the file itself is never uploaded to a shared signing server where it could theoretically be intercepted or substituted in transit.
- Neither approach requires the private key to ever leave an HSM. The distinction is about the artifact’s exposure, not the key’s.
Client-Side vs. Server-Side Hashing
| Client-Side Hashing | Server-Side Hashing | |
|---|---|---|
| What’s uploaded to the signing service | Only the hash (a few bytes) | The full artifact |
| Bandwidth for large artifacts (firmware, installers) | Minimal | Scales with artifact size |
| Artifact exposure in transit | None, the file never leaves the build environment | Full artifact traverses the network to the signing server |
| Implementation complexity | Requires client-side tooling to compute and submit the hash correctly | Simpler client integration; server handles hashing |
| Best fit | Large artifacts, bandwidth-constrained or high-volume CI/CD pipelines | Simpler setups where artifact size and transit exposure are less of a concern |
Now, let’s understand the Server-side Code signing in detail.
The following steps are performed while signing the code or any executable in a Server-side signing fashion:
- A unique key pair is generated and based on this key pair a CSR (Certificate Signing Request) is generated by a requester/developer.
- The CSR is sent to CA (certificate authority) with a code signing template.
- CA issues the certificate post validation and returns the code signing certificate with the public key to the requester.
- The code/executable to be signed is uploaded to the Code signing server by the requester.
- Once the code/executable is uploaded, the hash value of the code/executable is calculated with the help of any cryptographic hash function and since this hash value is computed on the server-side, hence the name Server-side hashing.
- The computed hash value is signed by the corresponding private key issued to the requester results in the digital signature.
- The digital signature, code signing certificate, and hash function information are now combined into a signature block and placed into the software, which is sent to the receiver/consumer.
- When the code/executable is received, the consumer’s computer first checks the authenticity of the code signing certificate.
- Once the authenticity is confirmed, the digest is then decrypted with the public key of the created key pair.
- The hash function is used on the code/executable to calculate the digest.
- The resulting digest is compared to the digest sent by the requester. If the digests match, then the software is safe to install.
Let’s understand the Client-side signing in detail.
The following steps are performed while signing the code or any executable in a Client-side signing fashion:
- A unique key pair is generated and based on this key pair a CSR (Certificate Signing Request) is generated by a requester/developer.
- The CSR is sent to CA (certificate authority) with a code signing template.
- CA issues the certificate post validation and returns the code signing certificate with the public key to the requester.
- The hash value of the code/executable is calculated with the help of any cryptographic hash function at the client end itself. Since this hash value is computed at the client-side, hence the name Client-side hashing.
- The hash value only i.e., digest of the code/executable to be signed is uploaded to the Code signing server by the requester.
- The computed hash value is signed by the corresponding private key issued to the requester results in the digital signature.
- The digital signature and hash function information is sent back to the client.
- The digital signature, code signing certificate, and hash function information are now combined into a signature block and placed into the software at the requester/developer end.
- When the code/executable is received at the consumer end, the consumer’s computer first checks the authenticity of the code signing certificate.
- Once the authenticity is confirmed, the digest is then decrypted with the public key of the created key pair.
- The hash function is used on the code/executable to calculate the digest.
- The resulting digest is compared to the digest sent by the requester. If the digests match, then the software is safe to install.
Frequently Asked Questions
Does client-side hashing make the private key more secure?
Not directly. In both approaches, the private key should remain in an HSM and never leave it. What client-side hashing changes is whether the full artifact travels over the network to reach the signing service, not how the key itself is protected.
Is client-side hashing always the better choice?
Not universally, it depends on artifact size and pipeline volume. For large firmware images or high-volume CI/CD pipelines, avoiding full-artifact uploads matters. For smaller, lower-frequency signing needs, server-side hashing’s simpler client integration may be the more practical choice.
Which approach does an enterprise signing platform like CodeSign Secure use?
Client-side hashing, computing the digest locally and submitting only that to the HSM-backed signing service, is the standard approach for enterprise CI/CD-integrated signing, since it keeps large artifacts off the signing infrastructure’s network path entirely.
Conclusion
Code signing has become a quintessential requirement for software developers and the reason is code signing ensures trust among users to install the software without worrying about anything. Although both the Code-signing methods are used in the industry to date, however, SolarWinds’ attack changed the code signing landscape in the industry a lot. Now, the client-side signing is a preferred choice considering the fact that it provides a significant advantage in terms of remote digital signature generation, reducing the overall bandwidth requirement due to only hash value upload, and avoiding the attacks of malicious code signed due to no code file movement within the environment.
Resources: www.encryptionconsulting.com/education-center/what-is-code-signing/
