Use Key Name or Key Containers to Sign .NET Assembly

In many .NET projects, the assembly requires to be stongly named. Actually every project should be stongly named in .NET development for it's numerous advantages. Though I'll not talk on the benefits of stong names here.

I have seen that in many stongly named projects, a SNK (Strong Name Key) file is generated and then specified in the Assembly Key File property of the assembly from Visual Studio.

Specifing the SNK file directly to the assembly requires the assembly to be deployed to the production with the same SNK file or at least with a SNK file with the same name that was specified in the Assembly Key File property of the assembly while development.

This certainly doesn't look to be a good practice as it forces the customer to follow pre-defined SNK file names on production boxes. This will be an issue if the customer is already having an SNK file in production and wants to use the same SNK file for all the applications and assemblies. I believe that this a very fair ask for any customer.

To solve this issue, .NET development best practices defines a solution by using “Key Containers”. A key container is nothing but logical container that encapsulates the SNK file in itself. So when assemblies are generated they should not have any SNK file specified in Assembly Key FIle property rather the key container of the snk file should be specified in the Assembly Key Name property of the assmbly.

This gives lot of liberty to the customer as he can use any snk file by just putting that into the container at deployment time. At the deploment time a key container with the same name as specified in the assembly needs to be created which shall hold the SNK file for the assembly(ies). This SNK file can be any SNK file that the customer wants to use. This gives the customer control over signing the assembly rather developer doing it. Also, SNK file can be easily changed for the assemblies later without impacting other application using the same SNK file.

How to generate and use key containers:

1. Create a snk file that you want to use for signing the assemblies. Use the following command to generate key.snk file from .NET SDK command prompt.

sn.exe -k c:\key.snk

2. Create a key container and assign the snk file to it. Following command create a key container named "MyContainer" and also assigns the strong name, generated in step 1, to it.

sn.exe -i key.snk MyContainer

3. Specify the key container to the .NET assembly through Visual Studio.

Right click on the project and select Properties to get the following screen. Specify key container, "MyContainer", in the Assembly Key Name property as shown in the attached image.

4. To delete the MyContainer key container at a later stage, use the following command.

sn.exe -d MyContainer

References -

1. MSDN link describing the sn.exe tool and all its parameters - https://msdn.microsoft.com/en-us/library/k5b5tt23(VS.80).aspx 

Note: Key Containers are deprecated in .Net 2.0. Instead, use the environment variable to point to your SNK file from multiple projects in VS2005. Simply update the ".csproj" file to set the "SignAssembly" property to "true" and the "AssemblyOriginatorKeyFile" to the environment variable point to the SNK file (e.g. $(MY_KEY_FILE)).

Add the following following tags into the .csproj and provide them with the environment variable name. The SNK file will be picked up as pointed by the environment variable. In case environment variable returns blank value then the project will be buit without strong name:

<AssemblyOriginatorKeyFile>$(MY_KEY_FILE)</AssemblyOriginatorKeyFile>

<SignAssembly>true</SignAssembly>

KeyContainerScreenshot.jpg