Strong Name your assemblies with Team Build using a private key

In my last post, I talked about Strong Name and Digital (Authenticode) signatures and how they relate to each other. This post describes how you can strong name your .NET assemblies using Team Build without handing over your private key to developers. Remember from my previous post:

Strong names are secure only when the strong name private key is kept secret.

See these resources for further reading:

Overview

Partial & Full signing workflow diagram with Team Build

Setup Key Files

  • Create a password-protected private/public key pair (KeyPair.pfx) using the Visual Studio “Signing” tab within a project’s properties
  • Extract the public key from the key pair and copy it to a separate file (Key.snk)

sn.exe -p KeyPair.pfx Key.snk

  • Copy the KeyPair.pfx to your build server. I use C:\Program Files\MSBuild\KeyFile.pfx, because it can then be accessed by the $(MSBuildExtensionsPath) MSBuild property.
  • Move the KeyPair.pfx file to a safe & secure location. Keep the password secret as well.
  • Copy the Key.snk to a shared location where your developers can access it.

Setup Projects for Signing

For each assembly that you want to sign:

  • Open the Project Properties | Signing page
  • Select the [X] Sign the assembly checkbox.
  • Select the [X] Delay sign only checkbox.
  • Select <Browse…> from the key file dropdown.
  • Browse to the shared location and select the Key.snk file
  • The snk file will be copied to each project directory that you assign it to
  • Copy the key file from one of your projects into Solution Items so that you can use it for the test run configuration

Project Properties - Signing page

Setup Test Run Configuration for Re-Signing

If you want to instrument your assemblies and enable Code Coverage for your unit tests, then you need to specify a key file for re-signing.

  • Open the LocalTestRun.testrunconfig file
  • On the Code Coverage tab, select the key as the Re-Signing key file

Test Run Configuration dialog

Disable Strong-Name Verification on Developer Workstations

Since you are delay-signing with only the public key, .NET CLR assembly verification will fail with assemblies built locally. When the verification fails you won’t be able to run or debug the assemblies.

To overcome this in development, you need to disable strong-name verification for assemblies that you build locally and delay-sign with your public key.

  • Open a Visual Studio Command Prompt
  • Type:

sn.exe -tp Key.snk

The output will be something like this:

Console output of sn.exe -tp

  • Type:

sn -Vr *,7f668b9f3b05cdd1

  • This will disable strong name verification for all assemblies signed with your public key.

You can list current settings for strong name verification with:

sn -Vl

Installing the Private Key for Team Build

Since the private key (Key.pfx) is password protected – Team Build cannot access it. Thanks to Nagaraju Palla’s Blog: Using Password Protected Signing Keys in Team Build, we have a solution.

  • Logon to the Team Build server as the build service account
  • Open the project in Visual Studio
  • Build the project in Visual Studio
  • You will be prompted for the password to the private key file.
  • Enter the password
  • Close Visual Studio & Log off

The private key file is now installed in the build service account’s local certificate store and Team Build can access it without prompting for the password again. This certificate store is as secure as the build service account’s password. (Hint: Make it just as strong as your keyfile’s password)

Updating TFSBuild.proj Build Script

Team Build has access to the private keyfile and password. This allows it to fully-sign the assemblies.

To override the project settings and instruct Team Build to use the private keyfile and disable partial-signing, we need to set the CustomPropertiesForBuild property in TFSBuild.proj

  • Check-out your TFSBuild.proj build script
  • Search for the placeholder <CustomPropertiesForBuild> property (near line 130 by default)
  • Replace it with the following:
<CustomPropertiesForBuild>
  SignAssembly=true;DelaySign=false;AssemblyOriginatorKeyFile=$(MSBuildExtensionsPath)\Key.pfx
</CustomPropertiesForBuild>
  • Check-in your changes
  • Queue a build

Verifying Team Build output

To check that Team Build has correctly strongly named your assemblies, you can use the sn.exe utility to verify the strong name signature.

  • Open a Visual Studio Command Prompt
  • Type:

sn.exe -vf assemblyname.dll

You can also verify all your assemblies at the same time:

  • Open a Visual Studio Command Prompt
  • Type:

FOR %a IN (*.dll) DO sn.exe -vf %a

Summary

This technique allows you the full flexibility of using strong naming in your development environment but with an acceptable level of security of your private key. As long as your private key is kept secret, you can make an assumption that any assembly with a valid signature has been generated by your Team Build server. Best of all though, is that once the initial setup of the Team Build server is done, all your projects can leverage the infrastructure with minimal fuss.

6 Comments

  1. Posted May 7, 2008 at 9:45 pm | Permalink

    Does this approach work for TFS 2005? I can’t seem to get the customPropertiesForBuild signing bits to sign assemblies that are built on the team build server.

  2. Adam Hager
    Posted October 7, 2008 at 11:36 am | Permalink

    I must be missing a step, when I logged onto the build server using the build service account, I opened the project I am working on and built it however I was never prompted for a password. Please help!

  3. Gabe
    Posted February 13, 2009 at 10:18 am | Permalink

    Perfect. thanks for the great information. this fixed me right up!

  4. ed west
    Posted April 14, 2009 at 3:05 pm | Permalink

    yeah, when I login on build server with build service account, and compile the project in vs or msbuild, I am never asked for the password… ? anyone know how to do this? thanks. using vs2008 btw.

  5. ed west
    Posted April 14, 2009 at 3:49 pm | Permalink

    I found the answer:
    http://blogs.msdn.com/msbuild/archive/2005/09/26/474079.aspx

  6. Ska
    Posted June 26, 2009 at 12:05 pm | Permalink

    Thanks for such a detailed blog.. good work

    For people confused on the below step
    Installing the Private Key for Team Build
    1) Create one dummy project on the Build m/c and use the private key, it will ask for the password when u try to assign it using VS.
    2) Then build the project
    3) U r done.

    4) Now any other projects which wish to use the same private key will be build without any issues.


5 Trackbacks

  1. [...] choose Strong Naming and/or Digital Signatures for your .NET assemblies. In my next post I describe how you can Strong Name your .NET assemblies using Team Build without sharing your private key with [...]

  2. [...] Strong Name your assemblies with Team Build using a private key « Grant Holliday [...]

  3. By Team System News : VSTS Links - 03/18/2008 on March 19, 2008 at 12:03 am

    [...] Grant Holliday on Strong Name your assemblies with Team Build using a private key. [...]

  4. [...] Structuring Solutions For Team Development – Resources Post 23 10 2008 During my RDN tonight I mentioned a couple of resources around signing your assemblies with a PFX and getting Team Build to go through the signing process for you. The article is from Grant Holliday’s blog and is available over here. [...]

  5. [...] Strong Name your assemblies with Team Build using a private key [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*