In this short post, I will discuss strong-named assemblies in .NET and cover why and how you should use strong naming within your .NET projects.
First, there seems to be a misconception among many developers with whom I’ve worked that strong naming is a security measure. That is not the intent of strong naming! Instead, strong naming provides a means of uniquely identifying assemblies and providing evidence that the assembly to be loaded is indeed the one intended. A strong name consists of the following things:
- The assembly’s simple text name
- The assembly’s full version number
- The assembly’s culture information
- A Public Key
- A Digital Signature
Why Use Strong-Named Assemblies?
Based on your scenario, there are some distinct reasons why assemblies should be strongly named.
- If you plan to deploy your assembly to the Global Assembly Cache (GAC), the assembly MUST be strongly named. This is necessary because the GAC allows multiple versions of the same assembly to coexist simultaneously. Anyone who has been around long enough to remember Windows development in the past, especially prior to .NET remember the term “DLL Hell”. I know this term all too well and learned very quickly a long time ago what a pain it can be. Those are bad memories, so I will move on! I will discuss the Global Assembly Cache in another article.
- Strong names protect the version lineage of an assembly. If an assembly is strongly named, the assemblies it references must also be strongly named.
Strong naming relies upon asymmetric cryptography. Although the purpose of this article is strong naming, a very quick discussion of asymmetric cryptography is warranted. I will only take a shallow dive into asymmetric cryptography because this purpose of this article is to briefly discuss strong-named assemblies and not encryption.
Asymmetric Cryptography (Public Key Cryptography)
Public Key Cryptography (PKC) is a form of cryptography that requires two “keys” – a public key and a private key. The public key is known to all and the private key is only known to the individual. In a very simple example of PKC, if I decide to send an encrypted message to one of my friends, I use my friend’s public key to encrypt the message, then he uses his private key to decrypt it. If he then decides to send me an encrypted message, he uses my public key to encrypt it then I use my private key to decrypt. Makes sense, right? It is important to note that with PKC, only the public key can be used to encrypt, and only the corresponding private key can be used to decrypt.
How to Create a Strong Name Key Pair
Before strongly naming an assembly, you must first have a public/private key pair file. The key pair is used by the compiler to create the strong-named assembly.
Creating a strong name key pair is made very simple by Microsoft through use of the Strong Name Tool (sn.exe). To create a key pair using this tool, simply follow these steps:
- From the Start menu, select your version of Visual Studio in the All Programs menu, click Visual Studio Tools, then select the Visual Studio Developer Command Prompt menu. See the following image.
- When the Visual Studio Command Prompt window opens, invoke the Strong Name Tool using the following syntax: sn -k KeyFileName.snk. The Strong Name Tool has numerous switches that can be used with its invocation. The -k switch instructs the tool to create the public/private key pair with the name that you specify. You can specify the path to which the .snk file should be created. In the example below, I create a key pair named MyKeyPair and I write it to the c:\Temp folder.
- When the key pair has been created, the next step is to use it to strongly-name an assembly. This is easily accomplished within Visual Studio by right-clicking the project to be signed and selecting the Properties menu. The example below shows the Properties window for a sample class library that I have created.
- Browse to the .snk file and click Ok. The .snk is then associated with the project and when built, the resulting assembly will be strongly-named.
That’s it! Pretty simple. In the next article we take a look at how to extract the PublicKeyToken from a strongly-named assembly.