I recently developed a couple of plugins for Microsoft IE and Firefox/Mozilla Browsers. People these days (myself included) are getting more and more paranoid about software running on their machines. I want to know that any code running on my machine has not been tampered with in any way. In the case of Microsoft IE, it loudly complains if you try to load a plugin that is not digitally signed. We are only going to see more and more use of signed apps now that Microsoft is making it a requirement for 64 bit drivers in Windows 7.
In my travels I’ve gathered a fair amount of information about public key cryptography, document and code signing and specifically (and more usefully) how this is performed for Windows development. I’ll give a brief (for dummies style) intro to signing and a walk through of how to buy and sign code from start to finish. (at least as far as it worked for me) Its my hope that this might be the only article a developer needs to read if they want to produce a signed executable for Windows.
As usual (for my writing), this is the article i really wish i had found when i discovered I needed to do code signing. There are many paths branching off the course i describe. I found a process that worked for me. I’m sure there are other ways to do this.
Signing and Encryption in General:
Public Key Cryptography and document / code signing is based on the RSA algorithm for encryption plus a hash algorithm (usually SHA2).
There is not shortage of simplistic descriptions of RSA on the internet. Its is basically an equation for taking 2 very large prime numbers and combining them to produce a public key a private key and a shared exponent. Producing the key, especially finding suitable prime numbers is a bit of a CPU intensive process. Most people are familiar with the ability to encrypt with the public key and decrypt a message with the private key. ala PGP messaging. The often unappreciated trick here for code/message/etc signing is that the keys are arbitrarily interchangeable. This means that I can encode a message using the private key that only the public key can decode. This is what is used in the signing process. The private key encodes something about the original state of the document (like its hash code) that you can only decode with the public key. The important part being that only the owner of the private key can encode it in such a way that it will decode properly. NOTE: there are some brute force hacks to try to add data to the end of a document to force it to conform to the original hash. These attacks can be easily thwarted just by knowing the correct size of the file.
The hash is for reducing the size of the set of data needing to be encrypted. Since RSA is not a block cipher encryption like RC4, AES, Blowfish, etc it is extremely CPU expensive to use on blocks of data. It is combined with a hash code to encrypt data as a single large number. i.e. One single crypt/mathematical operation. This is analogous to how SSL will use RC4 or other block cipher in conjunction with RSA for optimization purposes.
How to get a code signing certificate.
Firstly, a code signing certificate is not exactly the same thing as a security certificate that you might get from say godaddy.com.
There are multiple “usages” for certificates. (called ‘Certificate Key Usage’) Most providers of certificates do not sell code signing certs. They usually just sell SSL certs. In fact ask Godaddy for a code signing certificate and they wont even know what you are talking about. (happened to me) Even though the keys may look the same and all the same math applies. The validation chain will not allow a key to be used for something other than its declared (purchased) purpose/usage.
Code signing certificates are expensive. I have heard that if you are an FOSS (open source) developer you can get a free certificate from Certum. But in most cases you have to pay someone to validate you are who you say you are. They are here to establish your identity so you can be trusted. I use Comodo since they seem to be the cheapest issuer in the default certification authority (CA) trees/root that are loaded by default on most machines/browsers. There are several other good issuers that are very expensive such as Thawte and Verisign.
The process of the cert issuer checking you out and making sure you really are who you say you are can be long and require many back and forths to check all the boxes. For individuals you must give proof of you identity. For corporations you need proof you ar ea corp. If you list a domain name as yours, the physical (street) address on the certificate MUST match the address for the domain. I assume the more expensive code issuers must do a more thorough background check?
Comodo typically provides 2048 bit keys for code signing.
How to use a code signing certificate.
There are several file formats that can hold a certificate either in full format (public and private) or in public format. Microsoft (as usual for MS) has their own formats that are not directly compatible with everyone else (They need conversion). Certificates can also be stored in a “certificate store”, usually attached to your browser of choice.
Relevant file formats.
- p12 – importable into Mozilla
When you finally get your code signing cert it is usually in the form of a link to an encoded page on a web server. This server will add the cert to you local cert store on that machine.
If you are using Mozilla, got to the certificate store and export it to .PEM or Backup to .P12 format.
Start up I.E and import this PEM or .P12 format cert.
Export the cert from IE as a .PFX file.
You need to get the signtool.exe from microsoft to sign code/apps.
Code certificates can be optionally time stamped to make them last longer than the prescribed time period. For example if your cert expires on Jan 1 2010, not only can you not sign any new code but anything that is signed with your certs is now considered to be unsafe. The act of including a time stamp that is itself signed proves that the document/app was signed in the period when your cert was valid. For instance I use Verisigns signed time stamp service at http://timestamp.verisign.com/scripts/timestamp.dll
Signing with a cert held in a pfx file. (not very secure if someone can get read access to your system)
signtool.exe sign /v /f $(ProjectDir)..\DennisSign.pfx /t http://timestamp.verisign.com/scripts/timestamp.dll $(TargetPath)
Sign with a cert held in a pfx file that has a password assigned. (More secure than above from read snoopers)
Sign with a cert held in local cert storage. Cert is locked down on you machine.
How to see apps that have certificates:
In windows just right click on a file and get its properties.If you see a ‘Digital Signatures’ tag you now it is signed. Unsigned apps/docs dont have this.
To see certificates for all your running processes get a program called ProcessExplorer. It is downloadable from the Microsoft site. Turn on the ‘Verify Image Signatures’ mode in procexp and it will show all valid certificates for all processes that have them.
How to programatically validate a code signing certificate:
MS has provided some API calls for validating code certificates. Check out the WinVerifyTrust() API call.
Links to useful stuff:
comodo – the best price i could find for code signing certs.
BobsGear – has some interesting comments on the subject
Code Signing – Wikipedia