Digital Signatures
Sign Your PAF With A Self Signed Certificate
Code Signing
Code signing lets you know the origin of a program's code and can also protect the code from being tampered with (if the code has changed in anyway, the digital signature will become invalid). Thus, code signing provides two security protections: authentication of the author, publisher, or distributor of a program and its source code; and ensures and keeps the applications integrity of the code itself.
A digital certificate is issued by a trusted third party (certification authority) that has verified the identity of a software publisher. A certificate is a set of data that completely identifies an entity, and is issued by a certification authority (CA) only after that authority has verified the entity's identity. A code signing certificate includes the format of the certificate, the serial number of the certificate, the algorithm used to sign the certificate, the name of the CA that issued the certificate, the name and public key of the entity requesting the certificate, and the CA's signature. When the software publisher signs the executable file with its private key, you can use the publisher's public key (retrieved from the certificate sent with the software) to verify the publisher's identity.
Timestamping
Timestamping is used to specify a time when a digital signature is made. This is needed to properly validate any signature. If a signature timestamp is present, the application which validates (verifies) the signature, will check whether the certificates involved into signature validation were valid at the moment of signing. If there's no timestamp for the signature, certificate validity is checked for the moment of signature validation, which is not always acceptable.
If you plan on having your PAF being used and expect it to be used by people for a long time, than you should be sure to make it a habit to start timestamping when signing your code. Reason being is because if the signing certificate expires and there's no timestamp, there's no way to verify that the signature was made at a time when the certificate was valid, so previously signed code may just "stop working". Timestamping involves a third party (usually your CA) attesting that you made the signature at a particular time. Regardless of when your certificate expires, somebody receiving the signed code can then verify that your certificate was valid at the time you signed it.
Self-Signed Certs
You can create a self-signed, code-signing certificate (SPC
- Software Publisher Certificate) in one fool-proof command, however, if digital signatures and certificate authorties are a whole new concept to you then it would be in your best interest to proceed with what I'm going to be discussing these next few paragraphs. This way you can get much more familiar with this practice as well as gain a better understanding for why this is important. I'll be walking you through the steps in the creation of your self-signed, digital certificate. The links to the utilities that I'll be using here are provided at the bottom of this page.
Creating a CA
REM I'm using Softables for the name but you may use whatever.
makecert -r -pe -n "CN=Softables CA" -ss CA -sr CurrentUser ^
-a sha256 -cy authority -sky signature -sv SoftablesCA.pvk SoftablesCA.cer
REM The caret symbol (^) allows for batch command-line to wrap lines.
This creates a self-signed (-r
) certificate, with an exportable private key (-pe
). It's named Softables CA, and should be put in the CA store for the current user. We're using the SHA-256 algorithm. The key is meant for signing (-sky
). The private key should be stored in the SoftablesCA.pvk
file, and the certificate in the SoftablesCA.cer
file.
Importing a CA
There is no point in having a CA certificate if you don't even trust it, so you'll need to import it into the Windows certificate store. You can use the Certificates MMC snapin from the command line like the following:
certutil -user -addstore Root SoftablesCA.cer
Creating a SPC
makecert -pe -n "CN=demon.devin" -a sha256 -cy end ^
-sky signature ^
-ic SoftablesCA.cer -iv SoftablesCA.pvk ^
-sv demon.devin.pvk demon.devin.cer
Much of this is the same as the snippet above, but we are providing an issuer key along with a certificate (the -ic
and -iv
switches).
After that task has completed we will then want to convert our certificate and key into a PFX file using the following:
pvk2pfx -pvk demon.devin.pvk -spc demon.devin.cer -pfx demon.devin.pfx
If you want to protect the PFX file, add the -po
switch, otherwise PVK2PFX creates a PFX file with no passphrase.
Code Signing
signtool sign /v /f demon.devin.pfx ^
/t http://timestamp.url AppPortable.exe
If you import your PFX file into the certificate store (you can use PVKIMPRT or the MMC snapin), you can then sign your code as follows:
signtool sign /v /n "Me" /s SPC ^
/t http://timestamp.url AppPortable.exe
Available Timestamp URLs
Some possible timestamping URLs forsigntool /t
are:
- http://timestamp.verisign.com/scripts/timstamp.dll
- http://timestamp.globalsign.com/scripts/timstamp.dll
- http://timestamp.comodoca.com/authenticode
- http://tsa.starfieldtech.com
!finalize
AppInfo.ini
section of the read me file for more information.
Now I'll show you how to sign your PAFs automatically as they are compiled. That's right my friend. As soon as PAL finishes making your PAF it'll already have been signed for you. By using this very simple macro I've written for my own environment you can accomplish the same thing. Here's how..
Note
This snippet will only work with the new Unicode NSIS3.;=#
; Set up some defines..
;
!define CERT `demon.devin.p12`
!define STAMP `http://timestamp.comodoca.com`
!define SIGNTOOL `signtool.exe`
;=#
; ${Finalize::Sign} "Signtool" "PFX" "Timestamp" "Program"
;
; Finalize::Sign = uses !finalize to digitally sign our package.
; Signtool = The path to your signing utility.
; PFX = You certificate file to sign with.
; Timestamp = The timestamping agency you wish to use
; Program = This should your output file
;
!define Finalize::Sign `!insertmacro _Finalize::Sign`
!macro _Finalize::Sign _SIGNTOOL _CERTIFICATE _TIMESTAMP _OUTFILE
!finalize `"${_SIGNTOOL}" sign /f "${_CERTIFICATE}" /p "" /t "${_TIMESTAMP}" /v "${PACKAGE}\${_OUTFILE}"`
!macroend
${Finalize::Sign} `${SIGNTOOL}` `${CERT}` `${STAMP}` `${PACKAGE}\${APPNAME}.exe`
Download
For those who are not .NET developers, you will need a copy of the Windows SDK and .NET framework. A current link is available here: SDK & .NET (which installs makecert in C:\Program Files\Microsoft SDKs\Windows\v7.1). Your environment may vary.MakeCert is available from the Visual Studio Command Prompt. Visual Studio 2015 does have it, and it can be launched from the Start Menu in Windows 7 under "Developer Command Prompt for VS 2015" or "VS2015 x64 Native Tools Command Prompt" (probably all of them in the same folder).