Code Signing: two worlds defined

I've always been a fan of code signing. There's "signing" to give the assembly a strong assembly name, and there's "signing" to verify the application hasn't been tampered with. (It irks me that they're named the same.) It finally gelled in my head the difference between the two. For my own reference, and for the benefit of others, here is a description of each:

Strong Name

Reason: This is necessary to install assemblies into the GAC and to include a library in a signed project. It is specific to managed code.
Benefits: This insures the library doesn't conflict with other dlls. It says nothing about the origin of the file.

Technique (Visual Studio 2005):
- In the project's properties, click on the Signing tab
- Check "Sign the assembly"
- In "Choose a strong name key file" choose New to generate a .snk file
- For other projects using the same .snk file, choose Browse in this dialog, and find the .snk file created previously

I like to use the same .snk file for all projects in a solution. When choosing Browse, it copies the .snk file. I additionally do this:
- Close the solution
- Move the .snk file to a central location, and delete the copies
- Open the project files in my text editor of choice
- Locate the .snk file reference, and modify the path accordingly
- Open the solution and rebuild

Technique (Visual Studio 2003):
- Use sn.exe from a Visual Studio Command Prompt to generate a .snk file ( or use VS 2005 :) )
- In the Assembly Info file in each project, add the path to the .snk file

Gotchas:
- This .snk file should be kept in secret. You can create a public key file using sn.exe worthy of distribution.
- If this is an absolute path into C:\Documents and Settings\User\My Documents\Visual Studio 2005\Projects\... and you check this file into source control, your team won't like you. Please use relative paths.
- VS 2003 only: the compiled code is signed from inside the build directory (e.g. /bin/Debug), so relative references need to start there. I often found I'd have a bunch of "..\..\..\..\.." in my key paths.
- VS 2005 only: the snk file is referenced from the project directory, so relative paths need to start there.

References:
- Using a strong name in .NET
- Demanding a strong name in a library

Verify Origin

Reason: This is necessary for Windows Mobile 5, and good practice. It is not part of managed code, but rather a part of Win32.
Benefits: This documents the binary file hasn't been changed since it was built, and the builder can be trusted. It uses a chain of trust to a central trusted root certificate to insure the author is indeed who they say they are.

For production use, you should buy a certificate from Verisign or another trusted provider. Ramon has suggested a free provider: http://www.cacert.org/. I haven't reached the same level of trust he has, and can't comment on using it though. For testing, you can create a "self certificate". It doesn't tie to a trusted root certificate, but can be installed on a client machine as a trusted source.

Technique:
- From a Visual Studio Command Prompt, do this once:
makecert -r -sv app.self.pvk -n "CN=AppCert" -b 01/01/2000 -e 12/31/2050 app.self.cer
pvk2pfx.exe -pvk app.self.pvk -spc app.self.cer -pfx app.self.pfx
Substitute "app.self" and "AppCert" in both commands for what ever descriptive info you'd like.
Modify the beggining (-b) and ending (-e) dates as necessary.
Use MSDN or makecert -! for other parameters.

- After building the project each time (and signing for strong naming), run this command:
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\signtool.exe sign /f ../../../path/to/app.self.pfx /d "Descriptive App" /du http://www.tempuri.org/ app.exe
Substitute "app.self" for the actual .pfx file, and other info with info relative to your app and your organization.
I like including this as a post-build event on the solution.
An NAnt task would also be a great place to put this command.

Gotchas
- These .pvk, .cer, and .pfx files should be kept in secret. Handing them out defeats the purpose.
- Post-build events are run from the build directory (e.g. /bin/Debug), so relative paths have to start from here

References:
- Sign your redistributables quick and easy
- Signing assemblies for Windows Mobile 5


Conclusion

With both of these in place, you can look at an exe or dll and know that:
- It is uniquely named
- It is unaltered since it was built and the builder can be trusted

The other point of note: .snk sign first, .cer sign second. .snk is .net specific, .cer is bigger than that.

Rob

posted @ Wednesday, November 29, 2006 11:15 AM

Print

Comments on this entry:

# re: Code Signing: two worlds defined

Left by Joel "Jaykul" Bennett at 7/20/2007 4:50 PM
Gravatar
Ascertia.com also offers free certificates. They have two sub-root certificates, one signs "verified" identity certificates, and a second signs certificates where they merely verify the email address -- these are free.

It's much easier to get since they don't require you to personally meet and get signatures from dozens of people to climb the "trust ladder" ... on the downside, it's not particularly trustworthy.

In any case, creating and establishing trust for a certificate from Ascertia is certainly easier than creating one on your own ...

# re: Code Signing: two worlds defined

Left by John at 5/19/2008 12:28 AM
Gravatar
Ascertia provide the free digital code signing certificate but for the information, It is not trusted source.

# re: Code Signing: two worlds defined

Left by John at 5/19/2008 12:30 AM
Gravatar
Ascertia is not the trusted source for code sign certificate.

# re: Code Signing: two worlds defined

Left by steve981 at 9/1/2008 8:27 AM
Gravatar
Hi,
Is there a way to programatically determine an assembly's "signing" to verify the application hasn't been tampered with?

# re: Code Signing: two worlds defined

Left by parke at 9/5/2008 10:17 PM
Gravatar
Thank you.

# re: Code Signing: two worlds defined

Left by George at 10/5/2008 11:45 AM
Gravatar
You will want to distribute the .cer file since it contains the public portion of the public/private key pair of the PKCS system. This public key is then use to encrypt and decrypt data encoded by the private corresponding private key, which aught to be kept private.

The .pvk file contains the private key. The .pfx contains both the private and public keys and is typically used to hold a backup or copy of a keys pair.

Your comment:



 (will not be displayed)


 
 
 
Please add 1 and 3 and type the answer here:
 

Live Comment Preview: