How to Correctly do SHA-256 Code Signing:
The Real Scoop on Code Signing, SHA-256, and Windows 10

(by Chris Long / SSE Software)

Code signing used to be pretty simple. Most everyone had a SHA-1 certificate and signed their files with the SHA-1 algorithm. Then things got complicated. Ever since Microsoft announced that they were deprecating SHA-1 and making changes in regards to the trusting of files signed with SHA-1, there has been a lot of confusing and inaccurate information floating out there about what it all really means. This article seeks to give you the true, practical, bottom-line information you need to know as a software developer and give you good advice on how to sign your files.

Understanding the Basic Terminology

First, let's get our terminology straight. There are 3 major issues: what the algorithm of your certificate itself is, what signing algorithm you use ("digest algorithm"), and what the algorithm of the timestamper you use is. They can all be different. For instance, your certificate itself might be SHA-256, but you could sign your files with the SHA-1 algorithm and/or timestamp with SHA-1, etc.

Having the Right Certificate

If your code signing certificate was issued in 2014 or later, it probably is already a SHA-256 certificate. As of January 1, 2016, Windows 7 and above require your files to be signed with a SHA-256 or higher certificate [files that were previously signed with a SHA-1 certificate and were timestamped before 1/1/2016 may still be trusted for a few years, however]. So, since we are now in 2016, you should definitely first make sure you have a SHA-256 certificate. You can tell what your certificate is by looking at a file signed with it and right-clicking on it in Explorer and then clicking Properties->Digital Signatures tab->Details button->View Certificate button->details tab->Signature algorithm field.

As long as you don't care about supporting XP SP2 or earlier or Vista SP1 or earlier, you only need a SHA-256 certificate. Let me just tell you right now that you'll complicate your life a lot if you decide you really want to support XP SP2 and Vista SP1 or earlier because you'll need to have two different certificates. Best just to go with XP SP3+ and Vista SP2+ and go with a SHA-256 certificate. The rest of this article assumes you only have a SHA-256 certificate.

The Problem

As long as your certificate itself is SHA-256 or higher, then even if you sign your files with the SHA-1 algorithm (which is usually the default), they should still be fine for now unless Microsoft feels an attack on SHA-1 becomes possible (in which case all bets are off). However, even if there's no problem there, come February 2017, Windows 10 will stop fully trusting files that have been timestamped with SHA-1 and came from the Internet (so-called "Mark of the Web" files).

Given this, it would seem logical to just go ahead and forget SHA-1 and both sign and timestamp files with the SHA-256 algorithm and not worry about anything. Unfortunately though, it's not that simple. This would be fine if you are only intending to support Windows 7 or higher. However, if your software is still intended to be run on XP or Vista, this is a no-go. There's lots of confusing and contradictory information out there about XP's and Vista's support of SHA-256. Let me just cut to the chase and give you the bottom-line: They don't support it. I don't care what other articles you may read that say they do. They just plain don't. While XP SP3 and Vista SP2 (with extra update KB2763674) both technically support SHA-256 certificates (for User Mode anyway), they still have various issues when the algorithm (either signing and/or timestamping) is SHA-256 and thus in my experience, they are just not practically workable across-the-board with SHA-256. The only way XP SP3 and Vista SP2 (with KB2763674) will be truly happy is if you sign with a SHA-256 certificate but still have your signing algorithm ("digest algorithm") and timestamper algorithm be SHA-1. So what to do?

Dual-Signing

This is where the concept of dual-signing comes in. XP & Vista are only truly happy when signed with SHA-1. Windows 7 and above are (or will be) only truly happy when signed with SHA-256 or higher. To satisfy both, you must sign your files twice: once with the SHA-1 algorithm and SHA-1 timestamper, and then another time with the SHA-256 algorithm and SHA-256 timestamper. There's a major catch to this too though in that you can only actually do the dual-signing on Windows 8 or above (or Windows 7 with a workaround - more info below). Be advised however that dual-signing does not work for .MSI files so you might want to first wrap your MSI in an .EXE file (or use a non-MSI installer such as SSE Setup).

How to Sign / The Best Way to Sign

The main signing tool is SignTool (signtool.exe) and is provided by Microsoft. However, there is a much easier solution out there. SignTool is only available by downloading the Windows SDK, only operates via the command-line, and is NOT a redistributable file. Instructions for using SignTool are further below. However, an alternative is a free and ultra-simple program called EZSignIt. EZSignIt is both a GUI and command-line program (works either way) and already knows several SHA-1 and SHA-256 timestamper URL's that you can choose from. You simply pick your file to sign, your certificate, and specify whether to sign as SHA-1, SHA-256, or to Dual-Sign, and it'll do it. It also conveniently remembers your settings for future use, allows you to batch sign multiple files at once, and automatically verifies/validates files it signs. Basically it's just a lot easier than the SignTool approach. It also will detect if you are on Windows 7 and want to Dual-Sign and will provide you information on a pretty easy workaround to get dual-signing working on Windows 7! On top of that, it comes with a help file with full info on signing in general and how to sign.

Thus my recommendation is for you to use EZSignIt to handle signing (download it here). Even if for some reason you decide you still want to use SignTool, EZSignIt can optionally use SignTool to actually do the signing (it will automatically pass it the right command-line) and thus you still get the benefit of being able to sign via a GUI interface and/or do easy batch signing. So that program is a really helpful and simplifying thing and keeps you from having to muck-around with the SignTool command-line and/or having to run SignTool twice with different command-lines for dual-signing (EZSignIt only has to be run once).

Using SignTool

See the section directly above this for my suggestion to NOT use SignTool directly and instead use the free EZSignIt tool. However, if you still do want to use SignTool, here's what you need to know.

First, the command-line will be different depending on how you specify your certificate (i.e. whether it's in a .PFX/.P12 file or just in your local certificate store). The examples below assume it is a .PFX file. However, if that's not the case such as with Extended Validation/EV certificates, then you can substitute the /f and /p parameters for /n "IssuedTo Name on Certificate".

SHA-1 Sample SignTool line: SignTool.exe /f "C:\MyFolder\MyCert.pfx" /p "PFX Password" /t "http://timestamp.comodoca.com/authenticode" "C:\MyFolder\MyFile.exe"

SHA-256 Sample SignTool line (NOT dual signing): SignTool.exe /f "C:\MyFolder\MyCert.pfx" /p "PFX Password" /fd sha256 /tr "http://timestamp.comodoca.com?td=sha256" /td sha256 "C:\MyFolder\MyFile.exe"

SHA-256 Sample SignTool line (Dual signing): SignTool.exe /f "C:\MyFolder\MyCert.pfx" /p "PFX Password" /fd sha256 /tr "http://timestamp.comodoca.com?td=sha256" /td sha256 /as "C:\MyFolder\MyFile.exe"

If you are dual-signing, sign with SHA-1 first and then sign with SHA-256 per the related-example above. Note that dual-signing will require the version of SignTool from the Windows 8.1 SDK or higher, and signing with SHA-256 at all will at least require the Windows 7 SDK version of SignTool. If you try to use a version of SignTool that doesn't support SHA-256 or dual-signatures, it won't work.

Conclusion

The bottom line for most developers is: (1) get a SHA-256 certificate, (2) Dual-Sign your executables/DLL's using the free EZSignIt tool. The resulting signed files should work on XP SP3+ and Vista SP2+ (with KB2763674) and also work correctly on newer OS's such as Windows 10.

[Disclaimer: The advice and opinions in this article are strictly my own and are based on lots of investigation and testing. I've tried to simplify it all down for you as much as possible. I shall not be liable in any way for any advice or opinions shared here. It is your responsibility to do your own research, make your own mind up, and choose your own course of action based on your specific needs.]


 
Copyright © by Chris Long 2016. All rights reserved.