Authenticode Signing for Game Developers
Authenticode Signing for Game Developers
XNA Developer Connection (XDC)
December 2006
Updated: August 2007
Introduction
Data authentication is increasingly important for game developers. Windows Vista has a number of features, such as parental controls, that require games to be properly signed to ensure that no one has tampered with the data. Microsoft Authenticode enables end users and the operating system to verify that program code comes from the rightful owner and that it hasn't been maliciously altered or accidentally corrupted. This article discusses how to get started with authenticating your game and how to integrate authentication into a daily build process.
Background
Digital certificates are used to establish the identity of the author. Digital certificates are issued by a trusted third party known as a Certificate Authority (CA) such as VeriSign or Thawte. The CA is responsible for verifying that owner is not claiming a false identify. After applying to a CA for a certificate, commercial developers can expect a response to their application in less than two weeks.
After the CA decides that you meet its policy criteria, it generates a Code-Signing Certificate (CER) that conforms to X.509, the industry-standard certificate format created by the International Telecommunications Union, with Version 3 extensions. This certificate identifies you and contains your public key. It is stored by the CA for reference, and a copy is given to you electronically. At the same time, you also create a private, key which you must keep safe and which you must not share with anyone, even the CA.
After you have a public and private key, you can then begin distributing signed software. Microsoft provides tools to do this in the Platform SDK. The tools utilize a one-way hash, produce a fixed-length digest, and generate an encrypted signature with a private key. They then combine that encrypted signature with your certificate and credentials into a structure known as a signature block and embed it into the file format of the executable. Any type of executable binary file can be signed, including DLLs, executable files, and cabinet files.
The signature can be verified in multiple ways. Programs can call the CertVerifyCertificateChainPolicy function, and SignTool (signtool.exe) can be used to verify a signature from the command-line prompt. Windows Explorer also has a Digital Signatures tab in File Properties that displays each certificate of a signed binary file. (The Digital Signatures tab will only appear in the File Properties of signed files.) Also, an application can be self-verifying by use of the CertVerifyCertificateChainPolicy API.
Authenticode signing is not only useful for data authentication by end users, but is also needed for Limited User Account Patching and by Windows Vista's parental controls. Future technologies in Windows may also require signed code, so it is strongly advised that all professional and amateur developers acquire a CER from a CA. More information on how this is done can be found later in this article in Using a Trusted Certificate Authority.
Game code, patchers, and installers can further leverage Authenicode signing by verifying files are authentic in code. This can be used for anti-cheat and general network security. Example code for checking if a file is signed can be found here: Example C Program: Verifying the Signature of a PE File, and example code for checking ownership of a signing certificate on a signed file can be found here: How To Get Information from Authenticode Signed Executables.
Getting Started
To get started, Microsoft provides tools with Visual Studio 2005 and in the Platform SDK to help perform and verify the code-signing process. After installing Visual Studio 2005 or the Platform SDK, these tools are in one of the following subdirectories, respectively:
- %SystemDrive%\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin
- %SystemDrive%\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Bin
The following tools are the most useful for signing code:
- Certificate Creation Tool (MakeCert.exe)
- Generates a test X.509 certificate (CER) containing your public key and .pvk file containing your private key. This certificate is only for internal testing purposes and can't be used publicly.
- pvk2pfx.exe
- Creates a Personal Information Exchange (PFX) file from a CER and PVK file. The PFX contains both your public and private key.
- SignTool (SignTool.exe)
- Signs file using the PFX file. SignTool supports signing DLL, EXE, MSI, and CAB files.
Note While reading other documentation, you might find references to SignCode (SignCode.exe), but this tool is deprecated and is no longer supported — you should use SignTool instead.
Using a Trusted Certificate Authority
To obtain a trusted certificate, you must apply to a Certificate Authority (CA), such as VeriSign or Thawte. Microsoft doesn't recommend any CA over another, but if you want to integrate into the Windows Error Reporting (WER) service, you should consider using VeriSign to issue the certificate because accessing the WER database requires a WinQual account which requires a VeriSign ID. For a complete list of trusted third-party certificate authorities, see Microsoft Root Certificate Program Members. For more information about registering with WER, see "Introducing Windows Error Reporting" in ISV Zone.
After you receive your certificate from the CA, you can sign your program by using SignTool and release your program to the public. However, you must be careful to protect your private key, which is contained in your PFX and PVK files. Be sure to keep these files in a secure location.
Example Using a Test Certificate
The following steps demonstrate creation of a test Code-Signing certificate, followed by the signing of a Direct3D sample program (called BasicHLSL.exe) using this test certificate. This procedure creates a CER and PVK — your public and private keys, respectively — which cannot be used for public certification.
In this example, a time stamp is also added to the signature. A time stamp prevents the signature from becoming invalid when the certificate expires. Code that is signed but lacking a time stamp will not validate after the certificate expires. Therefore, all publicly released code should have a time stamp.
To create a certificate and sign a program
-
Create a Test CER and PVK by using the Certificate Creation Tool (MakeCert.exe).
The following command-line example specifies MyPrivateKey as the file name for the PVK, MyPublicKey as the file name for the CER, and MySoftwareCompany as the name of the certificate. It also makes the certificate self-signed, so that it does not have an untrusted root authority.
makecert.exe -r -sv MyPrivateKey.pvk -n "CN=MySoftwareCompany" MyPublicKey.cer
-
Create a PFX from your PVK and CER by using pvk2pfx.exe.
The PFX file combines your public and private keys into a single file. The following command-line example uses the PVK and CER from the previous step to create the PFX in a file named MyPFX with the password your_password:
pvk2pfx.exe -pvk MyPrivateKey.pvk -spc MyPublicKey.cer -pfx MyPFX.pfx -po your_password
-
Sign your program with your PFX by using SignTool.
You can specify several options on the command line. The following command-line example uses the PFX file from the previous step, gives your_password as the password, specifies BasicHLSL as the file to be signed, and retrieves a time stamp from a specified server:
signtool.exe sign /f MyPFX.pfx /p your_password /v BasicHLSL.exe /t URL_to_time_stamp_service
Note The URL to the time stamp service is provided by the CA, and is optional for testing.
It is important for production signing to include a valid time stamp authority, or the
signature will fail to validate when the certificate expires.
-
Verify that the program is signed by using SignTool.
The following command-line example specifies that SignTool should attempt to verify the signature on BasicHLSL.exe by using all available methods while providing verbose output:
signtool.exe verify /a /v BasicHLSL.exe
In this example, SignTool should indicate that the certificate is attached, while also stating that it is not trusted, since it is not issued by a CA.
-
Trust the test certificate.
For test certificates you need to trust the certificate. This step should be skipped for certificates provided by a CA since those will trusted by default.
On only the machines where you want to trust the test certificate, run the following:
certmgr.msc
Then right click on Trusted Root Certification Authorities and choose All Tasks | Import. Then browse to the .pfx file you created and follow the wizard steps, placing the certificate in the Trusted Root Certification Authorities.
When the wizard completes, you can start testing with the trusted certificate on that machine.
Integrating Code Signing into the Daily Build System
To integrate code signing into a project, you can create a batch file or script to run the command line tools. After the project is built, run SignTool with the proper settings (as shown in step 3 of our example).
Be especially cautious in your build process to insure that access to the PFX and PVK files is restricted to as few computers and users as possible. As a best practice, developers should only sign code with the test certificate until they are ready to ship. Again, the private key should be kept in a secured location, like a safe or locked room, and ideally on a cryptographic device, like a smart card.
Another layer of protection is provided by using Microsoft Authenticode to sign the Windows Installer (MSI) package itself. This helps protect the MSI package against tampering and accidental corruption. Refer to the documentation for your MSI creation tool for more information about how to sign packages with Authenticode.
Revocation
In the event that the security of the private key is compromised or some security-related event renders a Code-Signing certificate invalid, the developer must revoke the certificate. Not doing so would weaken the integrity of the developer and the effectiveness of signing code. A CA can also issue a revocation with specific time; code signed with a time stamp prior to the revocation time will still be considered valid, but code with a subsequent time stamp will be invalid. Certificate revocation affects code in any applications that is signed with the revocated certificate.
Code-Signing Drivers
Drivers can and should be Authenticode-signed. Kernel-mode drivers have additional requirements:
64-bit editions of Windows Vista will prevent installation of all unsigned kernel-mode drivers, and
all versions of Windows will present a warning prompt when a user attempts to install an unsigned driver.
In addition, administrators can set Group Policy to prevent unsigned drivers from being installed on
Microsoft Windows Server 2003, Windows XP Professional x64 Edition, and 32-bit editions of Windows Vista.
Many types of drivers can be signed with a Microsoft-trusted signature — as part of the
logo program of Windows Hardware Quality Labs (WHQL)
or the Unclassified Signature Program
(formerly named Driver Reliability Signature) — which allows the system to fully trust these
drivers and install them even without administrative credentials.
At a minimum, drivers should be Authenticode-signed, because drivers that are unsigned or self-signed
(that is, signed with a test certificate) will fail to install on many Windows-based platforms.
For more information about signing drivers and code and related feature in Windows Vista, see
Driver Signing Requirements for Windows
on Windows Hardware Developer Central.
Summary
Using Microsoft Authenticode is a straightforward process. Once you have obtained a CER and created a private key, it is a simple matter of using the tools provided by Microsoft. You can then enable important Windows Vista features, such as parental controls, and let customers know that your product comes directly from its rightful owner.
More information
More information about tools and processes related to signing code, see the following links:
Cryptography Tools
Crypto API Tools Reference
Authenticode Overview and Turtorials
Digital Certificates
Deploying Authenticode
How To: Create Temporary Certificates for Use During Development