From Windows XP Service Pack 2
onwards, any application downloaded with a mainstream web browser
(Internet Explorer, Firefox, Opera) will display a Security Warning
dialog when executed.
Zone Identifier
The warning dialog is shown when an Authenticode-compliant* download tool writes an Alternative Data Stream (so the the NTFS file system must be in use) for a binary file using the IAttachmentExecute interface
(http://msdn.microsoft.com/en-us/library/windows/desktop/bb776297%28v=vs.85%29.aspx).
The Save method of this interface is used to create a stream called “Zone.Identifier” and writes to it the values:
[ZoneTransfer]
ZoneID=3
– “3” indicating an Internet download source.
References:
http://bit.ly/GUqsok
http://bit.ly/HaCR0Y
http://bit.ly/GROWtT
A digitally signed application will
be identified by its “Publisher” – usually a company name –
and this will be listed towards the top of the dialog.
*Microsoft's “Introduction to Code Signing”
http://msdn.microsoft.com/en-us/library/ms537361%28VS.85%29.aspx
In the case of an unsigned application, Windows will automatically apply the disconcerting label “The publisher could not be verified. Are you sure you want to run this software?”, and “Unknown Publisher” in place of a company name.
Running a signed application
From Windows Vista onwards (when
User Account Control is enabled), an additional dialog is shown when
Windows detects execution of an “Installer” under the following
conditions:
Installer Detection only applies to:
- 32 bit executables
- Applications without a requestedExecutionLevel
- Interactive processes running as a Standard User with UAC enabled
Before a 32 bit process is created, the following attributes are checked to determine whether it is an installer:
- Filename includes keywords such as "install," "setup," and "update."
- Keywords in the following Versioning Resource fields: Vendor, Company Name, Product Name, File Description, Original Filename, Internal Name, and Export Name.
- Keywords in the side-by-side application manifest embedded in the executable.
- Keywords in specific StringTable entries linked in the executable.
- Key attributes in the resource file data linked in the executable.
- Targeted sequences of bytes within the executable.
Note: The keywords and sequences of bytes were derived from common characteristics observed from various installer technologies
Reference: http://msdn.microsoft.com/en-us/library/aa905330.aspx
Again, a signed “Installer”
will be identified by a company name as the “Verified publisher”
of the application, and the dialog colored with prosaic hues. An
unsigned “Installer” will list the Publisher as “Unknown”
and be decorated with amber “hazard” colouring.
This is all part of Microsoft's
system for securing users from potentially malicious software where
origin and integrity cannot be tested and confirmed (with a
substantial recurring financial cost to software authors for
participating in the system).
Newer versions of Visual Studio
bundle all of the Microsoft tools necessary for digitally signing a
binary file with that programming environment.
Delphi developers are required to
source them elsewhere.
Getting
the tools
For the purposes of this article,
we're going to be generating our own private key and digital
certificate for signing executables. Links at the end of the
article expound upon these same ideas, detailing the steps involved
in acquiring a certificate from a recognised Certificate Authority
(CA).
There are limitations to a
self-created certificate; as an individual you are not a part of the
“chain of trust” that exists between the various issuing
organisations, and as a result, any binary file signed with the
certificate will not be validated by Windows (the “Unknown
Publisher” message will still be shown).
However, it can be a useful for
internal testing, or for preparing your build processes in
anticipation of adding a CA-sourced certificate at some future date.
To generate our private key and
signing certificate, four tools are needed:
makecert.exe
Cert2Spc.exe
pvkimprt.exe
signtool.exe
...and an additional DLL file,
“capicom.dll”.
There are various ways of obtaining
them (they used to be included in the .NET SDK, but this has since
evolved into the “Windows SDK”), one option is to download the
“Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)”
- a 570MB package.
Another is the “Windows SDK for
Windows Server 2008 and .NET Framework 3.5” - a whopping 1.3 GB
download.
Windows SDK for Windows 7 and .NET
Framework 4 (GRMSDK_EN_DVD.iso):
Windows SDK for Windows Server 2008
and .NET Framework 3.5 (6.0.6001.18000.367-KRMSDK_EN.iso):
In either case a tool capable of
browsing ISOs – such as the indispensable freeware/open-source 7zip
(http://www.7-zip.org/) - can be
used to locate the files inside of them without any protracted
CD-burning or other intermediate extraction.
If you opt for the former, open the
ISO, then the Setup folder, then the WinSDKTools
folder, and within that the cab1.cab file. Here you'll find 3
of the 4 tools above – extract these to a convenient location.
Within the cabinet the files are
named:
WinSDK_makecert_exe_5D21BAF1_83A4_4E71_998E_FF39C36EA905_x86
WinSDK_Cert2Spc_Exe_910B78B5_FBE7_44CD_867D_0F90509859B0_x86
WinSDK_signtool_exe_B2E1011D_2F14_488D_A056_C5BD55106409_x86
Rename these to:
makecert.exe
Cert2Spc.Exe
signtool.exe
...respectively. Note, though, that
the Windows 7/.NET 4 SDK does not include (as far as I can tell), the
“capicom.dll” file, so this must be downloaded separately (via
the webpage “Platform SDK Redistributable: CAPICOM”) – it's
available (at slightly under 2MB) here:
If you choose the later
option, open the ISO with a browsing tool (such as 7zip), open the
Setup folder, locate the WinSDKTools-WinSDKTools-common.0.cab
file, open this, and extract the four files:
capicom_dll.970E4F94_546F_49F3_BF1F_18BE6B938B02
Cert2Spc_exe.D7AE6AF7_EC98_4D5C_97F8_562E6B8AF64F
makecert_exe.E4279728_DED0_47AC_8B96_F1269703DEFB
signtool_exe.B68FF751_0B1A_4F33_B044_1871CB4B13CC
...then rename them to:
capicom.dll
Cert2Spc.exe
makecert.exe
signtool.exe
pvkimprt.exe is not
available in either distribution so, also, must be downloaded
separately. It can be found via the webpage “Office 2000 Tool: PVK
Digital Certificate Files Importer”
(http://www.microsoft.com/download/en/details.aspx?displaylang=EN&id=6563).
It's a self-extracting zip file,
but again, a tool like 7zip can browse its content without having to
execute it and step through the extraction wizard. When opened,
extract the file “pvkimprt.exe” to a convenient location. This
file is, in turn, a self-extracting zip. Open it with 7zip, and
extract “pvkimprt.exe”.
Generating
a certificate
With all of the required tools
available, we can now generate our private key and code signing
certificate.
Open a command prompt (type cmd in
the Run or “Start Search” box, or use Start->All
Programs/Programs->Accessories->Command Prompt), navigate to
the directory containing the tools, and execute them in the following
sequence (with all spaces and other punctuation as shown):
makecert.exe MyCertificateFile.cer -r -n "CN= MyCompanyName " -$ individual -sv MyPrivateKeyFile.pkv -pe -eku 1.3.6.1.5.5.7.3.3
This first step will produce a “self-signed” certificate. Substitute “MyCertificateFile.cer” with the name you want to give to the generated certificate (the name you choose is just a label, the value of the text is inconsequential to the outcome of later stages – in all instances it makes sense to retain the suggested extensions, though, for clarity); “MyCompanyName” with an appropriate value for your “Publisher” identity; “MyPrivateKeyFile.pkv” with a name to use for your private key store file.
For further information about the meaning of the command line switches added here, use the in-built help “makecert.exe /?”.
The string after the “eku”
switch indicates that the file to create will be a “code signing”
certificate.
When you run the tool, you will be
prompted to enter a “Private Key Password” - you will need to
provide this again in step 3, and each time you sign a file, so make
a note of the password you choose to use here.
cert2spc.exe MyCertificateFile.cer MyCertificateFile.spc
Replace “MyCertificateFile.cer”
with the name you chose to give your generated self-signed
certificate from step 1, and choose a matching name (again, just for
clarity – it doesn't have to match) to replace
“MyCertificateFile.spc”. This will create a “Software Publisher
Certificate” (SPC) from the “MyCertificateFile.cer” file – a
certificate equivalent to one that would be issued from a Certificate
Authority.
pvkimprt.exe -pfx MyCertificateFile.spc MyPrivateKeyFile.pkv
Replace “MyCertificateFile.spc”with
the name you chose for your Software Publisher Certificate (.spc
file) in step 2, and “MyPrivateKeyFile.pkv” with a name for the
file to be created by Pvkimprt – a “Personal Information
Exchange” (PFX) file – this is what will be used to for code
signing.
Pkimprt is a GUI wizard. When you
run it you'll first be asked to enter your “Private Key Password”
- the password you selected for step 1.
None of the default wizard values
need to be changed, so click through each successive form by clicking
Next (x3), then on the “Password” form, enter your Private Key
Password twice more, and click Next again.
On the “File to Export” form,
click the Browse button, navigate to the directory containing the
signing tools, and type a name for the PFX file – e.g.,
“MyPFXFile.pfx”, then click Next.
On the final wizard form,
“Completing the Certificate Export Wizard”, click the Finish
button to complete the procedure.
As a result of these steps, you
should now have four new files labelled something like:
MyPrivateKeyFile.pkv
MyCertificateFile.cer
MyCertificateFile.spc
MyPFXFile.pfx
Code
signing
To use our newly generated
certificate, we need signtool.exe and a target file. Suppose
we have a binary executable named “MyProgram.exe” - the syntax
for signing this file would be:
signtool.exe sign /f MyPFXFile.pfx /p MyPrivateKeyPassword /v /t http://timestamp.verisign.com/scripts/timstamp.dll MyProgram.exe
-
where “MyPrivateKeyPassword” is the password you chose in step 1
(note also that “timstamp.dll” is not
a misspelling).
Automating
the process
To
make things easier and avoid having to re-type long commands in the
case of a syntax error, it makes sense to string the tool commands
together in a batch file. See the listing below for two batch files
based upon the text of the steps listed above.
Generating
a private key, self-signed certificate, and PFX file:
MakeCert.bat
@ECHO OFF
makecert.exe MyCertificateFile.cer -r -n "CN= MyCompanyName " -$ individual -sv MyPrivateKeyFile.pkv -pe -eku 1.3.6.1.5.5.7.3.3
cert2spc.exe MyCertificateFile.cer MyCertificateFile.spc
pvkimprt.exe -pfx myCertificateFile.spc myPrivateKeyFile.pkv
Signing
a binary file:
SignBinary.bat
@ECHO OFF
signtool.exe sign /f MyPFXFile.pfx /p MyPrivateKeyPassword /v /t http://timestamp.verisign.com/scripts/timstamp.dll %1
To use the second batch file with a named binary, launch it with a parameter – the name of the target binary file, e.g., “SignBinary.bat MyProgram.exe”.
References
Signtool
example:
http://poweradmin.se/blog/2010/03/07/the-wizard-in-signtool-exe-digital-signing-for-dummies/
http://poweradmin.se/blog/2010/03/07/the-wizard-in-signtool-exe-digital-signing-for-dummies/
Code
Signing for Developers – a Delphi-orientated article covering the
same sort of territory, but addressing (in addition) sourcing and
using a Certificate Authority issued certificate:
http://www.wiscocomputing.com/articles/code-signing.htm
http://www.wiscocomputing.com/articles/code-signing.htm
A
Microsoft article explaining different methods for sourcing a code
signing certificate:
http://technet.microsoft.com/en-us/library/cc732597%28v=ws.10%29.aspx#BKMK_Anchor3
Using
Makecert to Create Certificates for Development:
http://www.digitallycreated.net/Blog/38/using-makecert-to-create-certificates-for-development
http://www.digitallycreated.net/Blog/38/using-makecert-to-create-certificates-for-development
How
to create your own certificate for signing ClickOnce manifests and
Strong Naming assemblies (highly recommended!):
http://www.uphillriver.com/CreateYourOwnCertificate.aspx
http://www.uphillriver.com/CreateYourOwnCertificate.aspx
Code
Signing for Developers - An Authenticode How-To (highly
recommended!):
http://www.tech-pro.net/code-signing-for-developers.html
http://www.tech-pro.net/code-signing-for-developers.html