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

(by Chris Long, developer of SSE Setup)

Updated October 2021

Code signing on Windows is a subject that often can be a confusing mess. This article hopefully will help clear some of that up.

Why sign?

Pretty much every software developer these days needs a codesigning certificate - it's just a reality. Without a code signing certificate, Windows will show a UAC dialog when users run your software with a somewhat scary dialog declaring you to be an "unknown publisher" and suggesting users might not want to run your software. But Windows might not even let users get that far, because if users use a Microsoft browser to download your software or are using Windows 8 and newer, users will be likely to encounter an even stronger warning (or even an outright block) suggesting that your software is potentially harmful and shouldn't be run and might not make it very obvious how users can bypass that warning to still run your software. This is due to Microsoft's "SmartScreen" technology. In addition, some antivirus software may also be more likely to flag non-signed software as suspicious and some organizations also may have security policy set so that all unsigned software won't run.

If, however, you sign your files with a certificate that is trusted by Windows, then often it will be much smoother sailing.

Types of Certificates

There's loads of certificates out there but we are talking about Windows codesigning certificates, of which there are basically 2 types:

1. Regular/Standard/OV. These are the cheapest and easiest to obtain. They do not require a hardware (i.e. USB) smartcard/dongle. The downside to this type is that Windows does not instantly fully trust these certificates and it will take a period of time for your certificate to become "trusted" by Windows' SmartScreen technology. This delay period could range in time from days to weeks to who knows...The more popular your software and the more examples "in the wild" of OK files that have been signed with the certificate will likely lead to a quicker outcome of it becoming trusted, but there are no guarantees. Once the certificate is trusted though, any software you then sign with that certificate should be trusted. This is one reason why when you get a certificate you should buy one that is valid for a minimum of 3 years so that you only have to go through this "no trust" phase every 3 years instead of every year etc. Basically if you buy this type of certificate, you are trading speed of trust by Windows for a cheaper price. If you buy this type of certificate, you usually need to complete the entire certificate purchasing and picking up process using either Internet Explorer 11 or Firefox browsers (you cannot use Edge, Chrome, Safari, or anything else) because only those 2 browsers have the necessary stuff in them to handle it. In general, you purchase your certificate, the company checks up on you and once you are verified (the procedure can take a few weeks), you then use the same browser to "pick up" your certificate. From there you can export the certificate (including private key) from the browser to a password-protected .PFX or .P12 file which you can then use for signing (see below).

2. Extended Validation/EV. These are the newer type that require a more "involved" check up on you/your business and usually cost quite a bit more than the regular ones. These are issued on a hardware (i.e. USB) smartcard/dongle that will be mailed to you and for which you will always have to have connected when signing. Compared to regular certs, they are trusted higher on Windows such as Windows' SmartScreen filter instantly seeing newly signed files as having reputation, whereas there could be a delay in this occurring with files signed with a new regular/standard one. Unlike the standard certificates, they use hardware-based signing (i.e. with a USB dongle) and do not use .PFX/.P12 files.

Issues in Signing

So, before we get to HOW to actually sign your files, first let's get some terminology straight. When discussing algorithms, there is the algorithm of the certificate itself and then the "signing algorithm" that you use to sign the files and these can be different. Modern versions of Windows (Windows 7+, including Windows 10 and 11) no longer trust SHA-1 algorithm certificates and they also don't trust any files that have been signed with SHA-1 because SHA-1 for signing purposes has been deemed insecure for years now. Most all certificates have been issued as SHA-256 or higher (i.e. SHA-384) for a number of years so you can be pretty sure yours is too. However, while the certificate itself may be SHA-256 or higher, it is important you do not use only a SHA-1 signing algorithm when signing (see below) as newer OS's won't accept that. However, older OS's (XP/Vista) only largely understand SHA-1. You might run across articles out there that claim XP and Vista support SHA-256, but when it comes to code-signed files signed (and timestamped) with SHA-256 or higher algorithms, they are flat wrong. XP/Vista are only really happy with SHA-1 signing (even though they might be OK with the certificate itself being SHA-256 or higher).

Dual signing?

This is where the concept of "dual-signing" comes in. Because those old OS's (XP/Vista) only like SHA-1 and newer OS's (7+) only like SHA-256 or higher, for a few years in recent times it became popular to "dual sign" where you would sign with both SHA-1 and SHA-256 (often using the same SHA-256 or higher certificate) and you could be reasonably sure it would work on at least XP SP3 and Vista SP2 also. Some people promoted that you needed to have a SHA-1 certificate too in addition to SHA-256 or higher certificate, but that wasn't necessarily the case, especially when talking about XP SP3 and Vista SP2. Usually you could use the same SHA-256 certificate but merely sign once using SHA-1 and once using SHA-256 or higher.

However, as time has marched on, and as the number of users even using XP/Vista has dropped to minuscule numbers, given that SHA-1 really isn't secure in any way, its use is not recommended and in general I recommend dual-signing now be avoided. I currently recommend that where practical, all software developers move on from XP/Vista support and sign only with SHA-256 or higher (and I actually recommend only SHA-384 or higher now). This means XP/Vista may not see your software as valid and that's just something you may need to accept. (it may not be as big of deal on XP anyway which doesn't have UAC/show scary UAC dialogs to users).

Time stamping

Time stamping is a pretty simple concept. Once you sign a file with your certificate, it is only valid for the life of your certificate so when your certificate expires, your file may not be trusted on Windows anymore. UNLESS you also have the file signed by a trusted timestamper service using a valid timestamping certificate that verifies WHEN your file was signed. If you do that, then usually even if your certificate expires, the file will likely remain valid and trusted on the OS (or at least won't become untrusted simply because your certificate expired.) This is why you pretty much want to ALWAYS also sign your files with a Timestamper server when signing files. Note that as of October 2021, I am not aware of anymore currently functioning trusted SHA-1 timestamper services. This means even if you choose to dual-sign (see above), you probably won't be able to timestamp for SHA-1 with a SHA-1 timestamper. They are all as far as I know SHA-256 or higher now. When timestamping, you should timestamp with the same or higher algorithm as you sign your files. So if you sign your files with SHA-384, it is best to timestamp with SHA-384 or higher as well. Some timestampers will respect the algorithm you use to sign files and automatically sign with the same or higher algorithm, and some just do their own thing and sign with whatever they want even if you explicitly tell them differently.

How to Sign / The Best Way to Sign

The main Windows signing tool that everyone talks about is SignTool (signtool.exe) and is provided by Microsoft. This is a command-line only tool that does NOT come with Windows, is not redistributable, and usually requires you to download and install a large Windows SDK to obtain (though you may have it already if you have Visual Studio installed). Instructions for using SignTool are further below.

However, there is a MUCH easier solution out there. There is a small free and ultra-simple program called EZSignIt. EZSignIt is both a GUI and command-line program (works either way) and already knows several timestamper URL's that you can choose from. You simply pick your file to sign, your certificate, and specify the signing algorithm (it defaults to SHA-384) and it'll sign and timestamp your file, using the same basic underlying signing mechanism that SignTool uses. It also conveniently remembers most of 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 whole lot easier than the SignTool approach. It can also do dual-signing if that's desired. On top of that, it comes with a help file with full info on signing in general and how to sign.

Full disclosure: EZSignIt is my tool - It was originally developed as a part of the SSE Setup Installer Platform to provide signing for SSE Setup created installers since SignTool is not redistributable and there were no other suitable options available (12+ years later and there still really aren't many options out there - let alone one that provides all that EZSignIt does!). While developed for, and included with, SSE Setup, the tool has been released as freeware to benefit the entire developer and codesigning community, and unlike SignTool, it is redistributable if you follow some conditions. Seriously, I doubt you are going to find a more straightforward and easy, yet functional way to do codesigning than EZSignIt and I'm not just saying that because I wrote it. :)

Plus, it can even still easily use SignTool to actually do the signing if you want (it knows SignTool's command-line and also allows you to customize it) so there's really no downsides and lots of upsides to using it (i.e. GUI interface in addition to command-line, easy batch signing, etc.) There are no catches to using it - it is safe and fully free software with no ads or anything like that. To download it, just go here

So I'm biased, but if you really want to muck around just with SignTool, have at it.

Using SignTool

See the section directly above this for my suggestion to NOT use SignTool directly. However, if you still do want to use it, 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).

Sample SignTool command-line for regular/standard certificate: SignTool.exe /f "C:\MyFolder\MyCert.pfx" /p "PFX Password" /fd sha384 /tr "http://timestamp.comodoca.com" /td sha384 "C:\MyFolder\MyFile.exe"

Sample SignTool command-line line for Extended-validation/EV certificate: SignTool.exe /n "MyCertificateIssuedToName" /fd sha384 /tr "http://timestamp.comodoca.com" /td sha384 "C:\MyFolder\MyFile.exe"

Obviously the "MyCert.pfx" and "PFX Password" part in the 1st example needs to be replaced by the actual filename and password of your certificate. The "MyCertificateIssuedToName" in the 2nd example needs to be replaced with the name your certificate was issued to and relies on the certificate being in Windows' user certificate store (usually EV certificates will automatically do this). These will sign using SHA-384 and will timestamp using the Comodo (Sectigo) timestamping server. This is just an example. In general it is best to use the timestamping URL of the provider that issued your certificate.

Oh My, the Blasted Password/Pin Prompts!

When signing files, particularly when signing with an Extended-Validation/EV certificate, you may be much more likely to be prompted for a password or pin for EVERY file you sign! That's no big deal if you're signing one file, but what about if you need to sign 10 files, or 100? Not cool, right?

You've got a couple of options. First, the EZSignIt tool mentioned above often can do group signing of files WITHOUT having to prompt for each file, but only prompt once. Another strong benefit to using EZSignIt over SignTool (see above).

Another option (or in addition to) is that the signing utility that may come with the EV certificate may have an option to limit password prompts, so look for such an option (it might be called "single logon" or something like that). This may make it so that you'll only be prompted one time when you insert your dongle and then not again as long as the dongle is inserted. At least that's the theory. In practice, there seem to be some issues with this in some cases where it hasn't worked or stopped working with some Windows updates.

There may be other solutions as well, but they often tend to be pretty involved/complicated.

The Signing Bottom Line

You need to pick whether you want a regular or Extended validation/EV certificate, and then pick whether to use SignTool or another solid option like EZSignIt, sign your EXE/DLL files with SHA-384 or higher and timestamp the files using the timestamp URL provided by your certificate issuer (ideally). Happy signing! :)

[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-2021. All rights reserved.