Vision

Establishing the public key token: the difference between –t and –T

April 2005

Introduction

When starting out doing SharePoint development, it won’t take too long before you learn about the importance of strong naming your web parts. It also won’t take you too long to find out how to retrieve the public key token of an assembly. However, when using the strong name tool to retrieve the public key token it makes a world of difference if you use the –t or –T option. It’s an honest and easy mistake to make, so this article provides background information which helps you to understand why these options are quite different from each other.

Background information

We’ll start with some background information about assembly names, public key tokens and the strong name tool. Each assembly consists of a four-part name which can be used to identify the assembly uniquely. This name consists of a friendly name, culture, developer and version part. If all four parts of the assembly name are specified we’ll call the name a fully qualified reference, otherwise it’s called a partially qualified reference. A fully qualified reference looks like this:

Myname, Version=1.0.0.0, Culture=en-US,PublicKeyToken= def148956c61a16b

The public key of the assembly name identifies the developer (or the organization). Most organizations use only one public key to sign their web parts with. Assemblies can be referenced using either the public key (which is 128 byte) or the public key token (8 byte).

The public key can be embedded in the assembly manifest. In other words, the public key is written into the physical image of the assembly. Assemblies with public keys also have a digital signature which is generated when the assembly is compiled. This digital signature provides a secure hash of the assembly manifest which itself contains hashes of all subordinate modules (within that assembly). The digital signature can be verified only with the correct public key, the signature can be generated only with the correct private key (corresponding with the public key). The digital signature ensures that the assembly cannot be modified after shipping time. Rogue parties have no chance of tampering with your assembly without the correct key file (to be precise, rogue parties can tamper with your assembly all they want, but the tampering will be noticed by the CLR which raises a System.IO.FileLoadException when the assembly is loaded, so no harm can be done).

A key file can be produced using the strong name tool (SN.exe) which is shipped with the .NET SDK. If you type the following from the command line: sn.exe –k mykeyfile.snk, a key file containing a public key and a private key is generated. In case you’re interested, according to the Don Box book “Essential .NET”, the size of the public key is 128 bytes + 32 bytes header information, the size of the private key is 436 bytes.

Now, in order to keep the size of assembly references and assembly display names reasonable it’s preferrable to use a public key token instead of the public key itself. The public key is 128 bytes, but the public key token is only 8 bytes and is a hash of the full public key.

Establishing the public key token

The point of the article was about how you can establish the public key token of an assembly. At this point we’ve covered enough background information to discuss that.

The easiest way to establish a public key token would probably be to copy a strong named assembly to the Global Assembly Cache (GAC), right-click it, view properties and copy the public key token. In an example assembly we’ve built for this article this results in the following token: 470bd532707c672d.

Another way would be to use the .NET framework IL disassembler tool to retrieve an assembly manifest which contains the public key and the public key token (this would render the same result as described in the previous GAC scenario).

Yet another way would be to use the strong name tool to establish the token. Now here’s the catch 22, the public key token can be calculated using either the –t or –T flag, but both options work quite differently, so mistakes are easy to make.

The –T option calculates the token based on the public key stored in an assembly manifest. You can use it like this:

Sn.exe –T [path]\MySimpleWebPart.dll

This results in the following public key token: 470bd532707c672d. This is the same (and correct) result we’ve seen in the GAC scenario.

If you would accidentally use the lowercase flag –t instead, the result would be quite different:

Sn.exe –t [path]\MySimpleWebPart.dll

This results in the following public key token: 858feabe059a91a3. This is an incorrect token. Using this value would result in errors when trying to import a web part to SharePoint.

The –t option calculates the token based on an .SNK file. Watch out, here comes the next catch, this .SNK file should contain only a public key, not a private key. So in this case the first step you take is generate an .SNK file containing a public key and a private key:

Sn.exe –k publicprivate.snk

After that, the private key portion should be removed using the –p flag, like so:

Sn.exe –p publicprivate.snk public.snkNow we have a key file containing just the public key. Adding this key file to a VS.NET project would result in the following error: “Cryptographic failure while signing assembly…” (because the compiler needs the private key in order to generate a digital signature). The key file consisting of just the public key can be used in combination with the –t flag, like so:

Sn.exe –t public.snk

This gives us the correct public key token (470bd532707c672d). By the way, as explained above, the following would result in an incorrect public key token:

Sn.exe –t publicprivate.snk.

If you would try the uppercase flag on any .snk file you will also run out of luck quickly, but at least the mistake is far more visible:

Sn.exe –T public.snk

This results in the following error: “Does not represent a strong named assembly”.

Conclusion

As we’ve seen, mistakes are easy to make when generating public key tokens using the strong name tool. But with a little understanding, these mistakes can be avoided. Using the strong name tool it’s safe to either use sn.exe –T myassembly.dll or sn.exe –t public.snk.

« back to overview page