If you are a Linux sysadmin or a developer, you probably already know how to create and sign a SSL certificate for your webserver.
But, if your corporate environment also has some Windows servers and applications, you may end-up in a situation, where you may have to digitally sign Windows files.
The process of digitally signing a Windows files such as EXE, or DLL, or OCX, or CAB files is know as Code Signing.
For this, you should purchase a Code Sign certificate from a trusted provider like Symantec, or Thawte, or Godaddy, etc.
Once you purchase your code sign certificate, then you should sign your file using a tool called signtool.
This tutorial explains the following:
- How to install SignTool in Windows 10 (and Windows 7)
- Default Code Sign Example using SHA1
- Code Sign using SHA256 Algorithm
- Code Sign using PFX file or P12 file (for Default SHA1)
- Code Sign using PFX file or P12 file (for SHA256)
- Additional SignTool Options
If you already have signtool installed on your machine, and looking for a quick snippet on how to code sign using default options, here it is. In this example, I’m signing thegeekstuff.exe file.
signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /v "c:\thegeekstuff.exe"
signtool.exe is part of Windows SDK. If you don’t already have it, you should first download install Windows SDK on your system.
Download Windows SDK
If you are installing it on Windows 7 machine, then download “Microsoft Windows SDK for Windows 7 and .NET Framework 4” from here.
If you are installing it on Windows 10 machine, “Windows 10 SDK” can be installed using one of the following two options:
- Download “Windows 10 SDK” standalone version and install it. (This is recommended option)
- Download “Visual Studio” and install it. “Windows 10 SDK” is part of Visual Studio.
If your system already has Visual Studio, then go to Control Panel -> Programs and Features -> Locate “Microsoft Visual Studio” -> Click on “Change” -> This will launch the visual studio installer.
Expand on “Publishing Tools” -> Expand on “Universal Windows App Development Tools” -> Under this, select “Windows 10 SDK” to install it.
Install Windows SDK
Once you’ve downloaded the appropriate package of SDK installer for your system, installing it is fairly straight forward, as you just need to follow the on-screen instruction.
The following is the summary screen of Windows SDK installation on a Windows 7 machine.
During the install of SDK, I got this warning message: “Some Windows SDK components require the RTM .NET Framework 4. Setup detected a pre-release version of the .NET framework 4.”
If you don’t have .NET framework installed, or don’t have the latest .NET, download and install it from here.
On Windows 7, you may get the following error message during installation of Windows SDK 7.1:
Installation of the “Microsoft Windows SDK for Windows 7” product has reported the following error: Please refer to Samples\Setup\HTML\ConfigDetails.htm document for further information. Please attempt to resolve the problem and then start Windows SDK setup again.
The above error happens when you are trying to install Windows SDK on a system where you have a newer version of Visual C++ 2010 installed.
The solution is to uninstall the following two components:
- Microsoft Visual C++ 2010 x86 Redistributable – 10.0.40219
- Microsoft Visual C++ 2010 x64 Redistributable – 10.0.40219
After you uninstall the above two, install the Windows SDK again, it should work properly without any issues. If you prefer, you can always go back and install the latest version of Visual C++ 2010 after installing the SDK.
Select Appropriate CSP and Hash Algorithm
When you purchase your code sign from a provider, sometimes they might ask you to do the process on Internet Explorer, this way, they can update your local digital certificate store appropriately.
When you purchase the code-sign, it will ask you to allow permission to perform a digital certificate operation on your behalf. Click “OK” here. This will perform a capture CSR operation.
During the purchase of code sign, make sure the following options are selected properly:
First, Make sure the Cryptographic service provider (CSP) is set to “Microsoft Enhanced Cryptographic Provider v1.0” (or above).
Second, verify that Signature hash algorithm is selected appropriately. You’ll have the following two choices here:
- I’m signing application that don’t run in kernel mode
- I’m signing kernel-mode drivers and software for Windows Vista and 7.
During this process, this will also create a new RSA exchange key. Click OK in the following dialog.
Finally, after your purchase the certificate, you can “Pickup” the certificate from the provider. During this process, it will ask again ask you for permission to perform digital certificate operation on your behalf. Click “OK” here. This will directly download the certificate from the provider to your local certificate store.
This downloaded certificate from your provider will then be used during the signtool process.
Example 1: Default Code Sign Example using SHA1
On Windows 7 (Or other older versions):
cd "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin" signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /v "c:\thegeekstuff.exe"
On Windows 10:
cd "c:\Program Files (x86)\Windows Kits\10\bin\x86" (or) cd "c:\Program Files (x86)\Windows Kits\10\bin\x64\" signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /v "c:\thegeekstuff.exe"
In the above command:
- signtool.exe – This is the Signtool Utility that is used to sign your EXE or DLL or CAB or OCX files
- sign – This is the sub-command for the signtool, which indicates that we’ll be performing the code sign process
- /a – “a” here stands for automatic. This option will select the best signing certificate automatically. Use this option when you may have multiple signing certificate. If you have only one signing certificate, you don’t need to provide this option.
- /t – “t” here stands time stamp server. Following the /t, you should specify the time stamp server URL. This is important. If you don’t specify this option, when your file is signed, it will not be time stamped. You can use any time stamp server URL. I’ve used the URL from verisign.
- /v – “v” here stands for verbose. This displays a detailed output of the signtool’s execution. This will also display appropriate success, error, and warning messages.
- “c:\thegeekstuff.exe” – This should be the last parameter, which is the full path and the name of the file that you want to code sign.
During the above command, it may pop-up the following window saying that it is signing data with your private exchange key. Click ‘OK’ here.
In this example, the following was the partial output of the above command. This shows that the given EXE file was successfully signed.
.. Issued to: The Geek Stuff Expires: Sun Jan 1 23:59:59 2020 SHA1 hash: DDF323EDB783 Done Adding Additional Store Successfully signed and timestamped: c:\thegeekstuff.exe Number of files successfully Signed: 1 Number of warnings: 0 Number of errors: 0
Verify Code Sign: After you’ve code signed your file, to verify, do this: Select the signed file -> right-mouse click -> properties -> Click on the “Digital Signatures” tab -> In the “Signature List”, select the signature, and click on “Details” -> Click on “View Certificate” to view the details of the certificate that is on this file.
On a side note, if you are using an earlier version of Windows like (Windows Visa, Windows XP, etc), the signtool supported an option called “signwizard”, which will launch a self-guiding code signing wizard that will help you sign the certificate as explained here. But, the signwizard is not supported anymore on the newer Windows System.
Example 2: Code Sign using SHA256 Algorithm
To code sign using SHA256, in the Windows command prompt, enter the following command.
signtool.exe sign /a /tr http://timestamp.geotrust.com/tsa /td sha256 /fd sha256 /v "c:\thegeekstuff.exe"
In the above command:
- /tr – “tr” here stands for time stamp server RFC 3161. For this, you have to make sure the time stamp server is a RFC 3161 support. If not, this will return an error message as shown below. I’ve used the geotrust.com URL. You can also use this RFC 3161 URL: http://timestamp.digicert.com
- /td – “td” here stands time server digest algorithm. This is used to request the specified digest algorithm (in this case, sha256) from the specified RFC 3161 time server. Make sure the /td switch is declared after the /tr switch. If you specify this before the /tr switch, then the timestamp will be returned from SHA1 algorithm and from SHA256 as you would hope for.
- /fd – “fd” here stands for File Digest Algorithm. By default when you don’t specify this parameter, it will use the SHA-1 algorithm. In this example, it will use the SHA256 algorithm to digitally sign the file.
Error 1: If you specify /t option (instead of /tr) when you give /td, it will throw the following incompatible option error message.
C:\> signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /td sha256 /fd sha256 /v "c:\thegeekstuff.exe" SignTool Error: The /t option is incompatible with the /td option.
Error 2: If you specify a non RFC 3161 timestamp URL, you’ll get the following SignTool Error: The specified timestamp server either could not be reached or returned an invalid response
C:\> signtool.exe sign /a /tr http://timestamp.verisign.com/scripts/timstamp.dll /td sha256 /fd sha256 /v "c:\thegeekstuff.exe" SignTool Error: The specified timestamp server either could not be reached or returned an invalid response. This may happen if you specify an RFC 3161 timestamp URL but used the /t option or you specified a legacy Authenticode timestamp URL but used the /tr option. SignTool Warning: Signing succeeded, but an error occurred while attempting to timestamp
Example 3: Code Sign using PFX file or P12 file (for Default SHA1)
PFX stands for Personal Information Exchange. It is also called as PKCS #12. This will typically create a file with .PFX extension or .P12 extension.
As shown in the previous examples, if the code sign certificate is on your IE (internet explorer) browser, or Chrome browser, then the above signtool.exe command will be able to access it automatically without any issue.
But, if you’ve used a browser (for example, firefox), or on a different OS like MacOS to get the certificate from your provider, then use this method. In that case, export the PFX file (or P12 file) from your browser to your local system. And then, use that as shown below.
For Default SHA1 using PFX file, do the following:
signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /f "C:\mypfxfile.pfx" /p "MySecretPwd!" /v "c:\thegeekstuff.exe"
In the above:
- Most options are same as what is explained in the previous examples except the following
- /f – “f” here stands for file. This option only supports the PFX file format.
- /p – “p” here stands for password. This password will be used to open the given PFX file.
Couple of points to keep in mind:
- If you have a non PFX format file. For example, SPC or PVK file, then you can use the pvk2pfx.exe file to convert those to PFX file format and use that in the above command.
- Also, if the PFX file doesn’t contain the private keys in it, then you should use the /csp and /k option to specify the CSP and private key file separately.
Example 4: Code Sign using PFX file or P12 file (for SHA256)
For SHA2 using PFX file, do the following:
signtool.exe sign /a /tr http://timestamp.geotrust.com/tsa /td sha256 /fd sha256 /v /f "C:\mypfxfile.pfx" /p "WrongPassword" /v "c:\thegeekstuff.exe"
If the password provided is not correct, or if you don’t specify the /p option for your PFX file, then you’ll get the following SignTool Error: The specified PFX password is not correct.
C:\> signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /f "C:\mypfxfile.pfx" /p "WrongPassword" /v "c:\thegeekstuff.exe" SignTool Error: The specified PFX password is not correct. C:\> signtool.exe sign /a /t http://timestamp.verisign.com/scripts/timstamp.dll /f "C:\mypfxfile.pfx" /v "c:\thegeekstuff.exe" SignTool Error: The specified PFX password is not correct.
Example 5: Additional SignTool Options
The following will sign the given file using the certificate that matches the given name:
signtool.exe sign /n "The Geek Stuff" /v "c:\thegeekstuff.exe"
In the above: /n – “n” here stands for name of the subject. i.e Subject name. This should match the exact subject name of the existing certificate located in your store. O
The following example will do a code sign on the given ActiveX control. This will display the given description and the URL when Internet Explorer prompts the user to install this ActiveX. This way, the user knows what this activeX is all about.
signtool.exe sign /f "C:\mypfxfile.pfx" /p "MySecretPwd!" /d "The Geek Stuff" /du "https://www.thegeekstuff.com/about" /v "c:\thegeekstuff.exe"
In the above example:
- Most options are same as what is explained in the previous examples except the following
- /d – “d” here stands for description. This is a brief description about the signed file.
- /du – “du” here stands for description url. This will display the given URL as an expanded description of the signed content.