Code signing your software
What is code signing?
According to Wikipedia, code signing is "the process of digitally signing executables and scripts to confirm the software author and guarantee that the code has not been altered or corrupted since it was signed. The process employs the use of a cryptographic hash to validate authenticity and integrity. Code signing can provide several valuable features. The most common use of code signing is to provide security when deploying; in some programming languages, it can also be used to help prevent namespace conflicts.
Why code sign your software?
When installing software, especially after downloading it from the Internet, it is imperative to exercise caution and ensure you (as an end-user) trust that the software has not been tampered with and does not contain malicious code (such as malware, ransomware, viruses, etc.). Because code-signing your applications verifies that all of the code came from your organization and nowhere else, your users and their security software (virus scanners, anti-malware utilities, etc.) will treat your digitally signed executables with less suspicion. On Windows, the software installers can be code signed so that the Window's User Account Control (UAC) prompt shows the author's company name as a verified publisher as shown below:
What do I need to know about encryption?
To understand how code signing works, you should have a rudimentary understanding of public-key encryption and hash functions.
Public key encryption uses two different keys, also called a key pair. One key of the key pair is a public key that others may know in full, while the other key is the private key which is only partially shared with others (only you know the "private" pieces of the key). The private key data is used for encryption and digitally signing the plain-text/original contents. Meanwhile, the public key data is used to decrypt the data received and verify the signature to ensure decrypted contents are unaltered and from the original and trusted source.
Hash functions are a means for one-way encryption that may not be decrypted. Think of the case where a user’s password is hashed and stored in a database. Whenever the user logs in, their login password is hashed and this hashed value is compared to the hashed value in the database. This allows the login to be validated, but an attacker who gains access to the database has no way of reversing the hashed passwords in order to use them.
How does code signing work?
For a developer, there are three things needed for code signing.
- A code signing certificate
- A code signing application
- Unsigned software files
The code signing certificate is generally purchased from a Certificate Authority (CA), while the code signing application likely comes with the Operating System or development tools.
The developer will locally generate a public/private key using a tool such as IIS Manager or Microsoft Management Console (MMC). A Certificate Signing Request (CSR) file is created containing the publisher information, the public key, and other information. This CSR is used by the Certificate Authority to create a code signing certificate.
Once the publisher has the code signing certificate, a hash is created of the file being signed (your application) using a code signing tool. This hash is then encrypted using the publisher’s private key mentioned above. This encryption of the hash is the "signature" in the code signing process. The output of this process along with the code signing certificate that contains the public key and the identity of the publisher is then added to the software to be shipped out by the code signing tool.
A code signing certificate will have an expiration, and an expired certificate will need to be renewed if you need to code sign your software again. But what happens to software that was already signed and distributed prior to the certificate expiring? Time-stamping solves this scenario by adding a cryptographically verifiable timestamp to the signature. The signature may then be additionally verified it was created before the code signing certificate expired, and if so, it will be treated as a valid signature. Instructions for time-stamping should be provided by the Certificate Authority.
When a user downloads the digitally signed software, the web browser or Operating System already contains its own copies of public keys from trusted Certificate Authorities in what is usually called a "key-store." The code signing certificate used to sign your software is then also verified against the appropriate Certificate Authority's public key / certificate to ensure that the signature itself was generated from a trustworthy Certificate Authority. The public key from the code-signing certificate issued to your organization (also referred to as the "publisher") is then extracted from the executable file and used to decrypt the encrypted hash data. A new hash is generated of the signed file and compared to the decrypted hash to verify the authenticity and integrity of your application.
Where should I purchase a code signing certificate?
There are a number of Certificate Authorities where a code signing certificate may be purchased. Here are just a few:
- GlobalSign: https://www.globalsign.com/code-signing/
- GoDaddy: https://www.godaddy.com/web-security/code-signing-certificate
- Thawte: https://www.thawte.com/code-signing/
This wiki article from Microsoft demonstrates how to generate a Code Signing Request needed to obtain the code signing certificate.
How do I code sign my software?
Once you have obtained a code signing certificate, it is time to use a code signing tool. On Windows platforms, Microsoft Authenticode technology is used to digitally sign executable and other file formats in order to embed information about the author and to provide a means of verifying the trustworthiness of the author and the integrity of the file to ensure it is safe and has not been altered.
The code signing tool SignTool.exe is available with the Windows SDK. Information on using SignTool can be found in the Microsoft documentation.
Code signing tips from Team SoftwareKey
Here at SoftwareKey, we have been code signing our installers, applications, and libraries for years and have a few tips we would like to share.
Renew your certificate with the same CA
When your code signing certificate needs to be renewed, we recommend renewing from the same CA rather than purchasing a new certificate from a different CA. Otherwise, Microsoft Defender SmartScreen on Windows could show a security warning that it prevented your application from running.
The user can click the More info link on the SmartScreen dialog and then have the option to run the application, and SmartScreen will eventually stop showing the warning once your software has been installed a certain amount of times (how many times is not shared by Microsoft). This security warning should not be shown if the code signing certificate is renewed from the same CA.
Use a build script
Automate your build process to include code signing at the end. It is so easy to miss a step in a manual build process, and you would hate to let a release slip out without signing your software! Consult your DevOps administrator or consultant to automate as much of your build and release process as possible.