Friday, February 19, 2016

Executable Signing Using SHA-256 Certificates

A few weeks ago, a customer complained that when they downloaded the installer for Stonefield Query, they got a warning that the download was corrupted. I tried it myself and couldn’t reproduce it, so I assumed their anti-virus software was the culprit. Then a second customer had the same problem, and then a third. Googling the error message led me to this article describing the real problem: executables signed with SHA-1 certificates (which ours are) are blocked after January 1, 2016 (although it appears to be an issue on some operating systems and not others because, as I said, the downloads worked for me). Although my certificate provider had been sending me emails about upgrading to a SHA-256 certificate, for some reason, I thought it only applied to web servers.

Several years ago, I discussed signing executables with Inno Setup (which incidentally is my most popular blog post ever). There are a few changes necessary to using a SHA-256 certificate with Inno Setup, so I thought I’d document the entire process here, even those things that aren’t specific to the new certificates.

Once you’ve purchased a certificate from your chosen provider, you’ll likely get an email with a link to download the certificate into the certificate store on your machine. Normally, you’ll want the certificate in file form to make signing easier, so you need to get it out of the certificate store after you’ve downloaded it. To do so, do the following:

  • Start the Certificate Manager snap-in by running CertMgr.msc.
  • The downloaded certificate is in the Personal\Certificates section. Right-click the certificate and select All Tasks, Export to bring up the Certificate Export Wizard.
  • In the Export Private Key step, choose Yes, export the private key.
  • In the Export File Format step, Personal Information Exchange (.PFX) is already selected. Make sure Include all certificates in the certification path is turned on (it should be by default). Turn on Export all extended properties.
  • In the Security step, turn on Password and enter a password.
  • In the File to Export step, enter the name of the PFX file to create.

You can then use SignTool to sign EXEs using the PFX file. SignTool comes with Microsoft Visual Studio and the Microsoft Windows SDK. If you don’t have Visual Studio, you can download the SDK from Microsoft’s web site; search for “download Windows SDK” to find the appropriate download page. You can typically find SignTool.EXE in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1a\Bin (the version number may be different depending on what version of the SDK you download and it may be in C:\Program Files instead). Here’s an example of a command to sign an EXE (the section highlighted in yellow is new for SHA-256 certificates):

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1a\Bin\signtool.exe" sign /fd SHA256 /tr timestampServer /td SHA256 /f certificatePath /p password /d "description" fileToSign

where timestampServer is the URL to your certificate provider’s timestamp server so the certificate can be timestamped (see your provider’s documentation), certificatePath is the path to the PFX file, password is the password for the PFX, description is the description for the digital signature, and fileToSign is the path to the EXE to sign. Remember to add quotes around any path containing spaces.

It’s actually even easier than that to sign the installer generated by Inno Setup. You can do it one of two ways:

  • In the Inno Setup Compiler, choose Configure Sign Tools from the Tools menu, click Add, specify a name (I use “Standard”), and enter something like the following for the command:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe sign /fd SHA256 /tr timestampServer /td SHA256 /f certificatePath /p password $p

Note there are no quotes in the path and that $p is a placeholder for the SignTool parameters specified in the [Setup] section. Then add the following to the [Setup] section of your ISS file:

SignTool=Standard /d $q{#MyAppName}$q $f

$q is a special symbol meaning insert a quote (you can’t use actual quotes here) and $f is a placeholder for the name of the file to be signed. This assumes you have a constant defined for MyAppName. If not, use whatever you wish for the description.

  • If you compile your ISS file using the Inno command line compiler, pass the following parameter to the compiler:

"/sStandard=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\ signtool.exe sign /fd SHA256 /tr timestampServer /td SHA256 /f certificatePath /p password"

Be sure to put the certificate in a path with no spaces in any of the folder names or you’ll get unhelpful error messages when you build the setup.

No comments: