Code signing provides integrity to your executables, ensuring that they have not been modified or corrupted. Many modern operating systems require code signing to protect their users from code that has no known origin or guarantees of authenticity.
Similar to HTTPS, trusted certificates created by Certificate Authorities are issued to individuals or companies to allow them to sign code that will be recognized by major operating systems.
One of the most important parts of code signing is timestamping. This is part of the signing process that allows software and users to recognize a valid code signing signature even after the certificate has expired.
If your software stops running as a result of an expired code signing certificate, consider the impact that would have on your users and how you would remediate it. Would you be able to push an update, or would that mechanism also be broken due to the expired signature? How much would it cost to develop and deploy a patch in an emergency? Would your users suffer business impacts of their own if your software stopped working?
Because of the high-impact of expired signatures, it’s extremely important that your code signing process is well understood and documented, and that you always timestamp your software to preserve the signature.
Timestamping is not only a best practice for continued usability of your software, but it also provides a security benefit. If you needed to revoke your certificate due to key compromise, anything signed before the revocation date will continue to function—and any new signatures will be invalid.
We will cover the background of timestamping and best practices to follow to ensure you never run into any unexpected problems with your software’s signature.
What is timestamping?
Timestamping preserves the signature on your software, allowing it to be accepted by operating systems and other software after your Code Signing Certificate expires. When the signature is evaluated, the timestamp allows the validity of the signature to be checked against the time it was signed, instead of the current time when the software is being executed.
Without a timestamp, the signature is evaluated against the current date. You may have distributed your software years ago, in which case, your certificate would have expired and the signature would no longer be valid. This would prevent a user from running your software, and depending on the platform, there may be no way to circumvent that.
For example, your code signing certificate was valid for the entirety of 2017 (1/1/2017 to 12/31/2017), and you signed and timestamped an executable file in November of 2017. A user downloads your executable and runs it today—instead of checking if the code signing certificate is currently valid, their OS checks the timestamp and evaluates if it was valid in November. It sees the certificate was valid then, and the signature is accepted.
Note that the signature on your executable is checked every time the user runs it. This means that if your certificate expires and there is no timestamp, the software will suddenly stop working for all your users.
With most software, you distribute it to users and want it to work for as long as possible—this makes timestamping an essential part of your signing process so that your software can continue to be used for years.
The timestamp itself is signed by your CA and protected, making it resistant to tampering or spoofing and cryptographically secure. Think of the timestamp as a counter-signature.
On Windows, timestamping also allows your signatures to remain valid if the CA who provided your code signing certificate is distrusted.
- The first and most important: Use timestamping! In many tools, such as Microsoft’s SignTool, timestamping is optional. Make sure you understand how timestamping works with your development tools. We provide documentation for the most popular environments, including Windows, Mac OS, and Java.
- Check platform support: SHA-2 is the modern standard algorithm for timestamping signatures. However, some operating systems still in use do not support SHA-2 by default—Windows 7 only supports SHA-2 with a patch. If you believe an older OS is popular amongst your users, consider if you should use a SHA-1 signature or dual-sign with two certificates to support both algorithms.
- Make it a part of your build process: As you update your software, you will build and release new executables. Ensure that signing and timestamping is a part of that process to avoid unexpected issues and errors with every version of your software.
- Document the process: You know your development tools and process better than anyone else. Timestamping requires additional flags and commands during the signing process, including a URL to retrieve the timestamp signature securely from your CA. Make sure that changes in staffing or procedure do not result in someone forgetting to properly sign your software.
- Limit damage of key compromise: Timestamping provides a way for operating systems to recognize if a signed executable was issued before or after a certificate revocation. In the event that you need to revoke a certificate due to key compromise, you can safely do so without invalidating the signatures you legitimately produced if you have timestamped them. The timestamp will be checked against the revocation date, and anything issued before that date will continue to be valid.
The Importance of Certificate Expiration
A common misunderstanding is that certificate expiration only exists as an opportunity for Certificate Authorities to charge you more money. From a technical perspective, certificate expiration is a fundamental part of PKI that is needed to make the system work, especially with the Web PKI where multiple independent parties are interacting.
One of the primary purposes of PKI is to bind an identity—such as a domain name, organization, or other unique identifier—to a public key. With any type of trusted certificate, that identity is validated to ensure accuracy. This gives you—and the software you use—the confidence to know that a certificate issued to DigiCert.com/DigiCert, Inc. is really owned by us. This is true for Code Signing, SSL, and email certificates.
For example, before you can receive a Code Signing certificate for Software Developers LLC., your CA vendor had to ensure that that company really exists, is properly registered and in good standing with your local government, and that you are really an employee of that company with authority to request the certificate.
Expiration acts as an opportunity for the CA to re-check this information to make sure that the bind between the identity and public key is still correct. In this way, a trusted certificate should be thought of as an identity document similar to a passport or driver’s license, which also expire. The government issuing you those documents wants to be able to occasionally insure the information is still accurate and that you still have the right to use and obtain that document.
Without expiration, certificates would work indefinitely, making the identity behind the key questionable as it aged. Companies and domains change hands, can be re-registered, and employees who may be in possession of these certificates leave. Would you trust that a certificate issued in 2010 was still possessed by the person it was issued to? What about a certificate issued in 2000?
Revocation is an additional mechanism which can indicate when a certificate should no longer be trusted—but there are a number of reasons (including performance, lack of revocation status checking in client software, and availability) that revocation could not be relied on as the primary method of invalidating certificates.
There are a number of other reasons certificates expire—it ensures that there is a limited window of time for that certificate to be maliciously used if it’s been compromised, provides an opportunity to re-key the certificate with a new key pair (a best practice), and upgrade to current cryptographic methods such as new signature algorithms or stronger keys.