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:
- MSDN: Delay Signing an Assembly
- MSDN Magazine: Using Strong Name Signatures
- Nagaraju Palla’s Blog: Using Password Protected Signing Keys in Team Build
Overview
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
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
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:
- 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
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.
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!
Perfect. thanks for the great information. this fixed me right up!
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.
I found the answer:
http://blogs.msdn.com/msbuild/archive/2005/09/26/474079.aspx
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
[...] 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 [...]
[...] Strong Name your assemblies with Team Build using a private key « Grant Holliday [...]
[...] Grant Holliday on Strong Name your assemblies with Team Build using a private key. [...]
[...] 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. [...]
[...] Strong Name your assemblies with Team Build using a private key [...]