Strong Name Signature: what and why
If you have ever felt confused about Strong Name, this article might be worth to read. A quick search on internet might tell you the following:
- Strong name is used for uniquely identifying an assembly
- Strong name signature is NOT recommended for security purpose
These statements might seem reasonable at first glance, however, more questions will be raised if you think more about it. In what sense could a strong name be used to uniquely identify an assembly? What if some one make two different assemblies and give them exactly the same strong name? Why a signed assembly might be insecure? If that is the case, what we sign it for? To answer these questions, let’s first review what a strong name is and what we are doing when strong name sign an assembly.
What is a strong name
Strong name is a ‘long form’ assembly name, which looks like this:
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
It is composed of the following parts:
– file name, System.Core
– Version, Version=4.0.0.0
– Culture, Culture=neutral
– Public Key Token, PublicKeyToken=b77a5c561934e089
What is a Public Key Token
Public key token is a 64-bits hash of the public key used to sign the assembly. The public key itself is also included in the assembly, but the token or hash is used in the strong name to make it more concise. As the underline hash algorithm is well know, everyone could easily valid the token from public key. As mentioned in some other articles, the token serves likes a name of the public key. However, it is not an arbitrary name: any given public key has only one valid name (public key token) and everyone can validate it! If people could use the same token for different keys, different publisher could use their own keys to sign different assemblies but assign them with exactly the same strong name! The public key token in strong name tells that this assembly was created by the owner of the corresponding public key. Different publishers, who never share ownership of their keys, will never be able to create assemblies with the same strong name. On the other hand, one publisher might use different key pairs for strong name signing thus might publish assemblies with different public key tokens.
What is done when strong name sign an assembly
Notice that we are talking about strong name signing instead of code signing, which is beyond the scope of this article. To strong name sign an assembly:
- Create a strong name for the assembly
- The text name, version and culture are set by the author
- The public key token is calculated from the public key
- Write the public key itself into the assembly
- Sign the whole thing with the private key
- Hash the whole assembly, with strong name and public key in it
- Encrypt the hash to generate a signature, which was appended to the assembly
How to validate the strong name signature
Like validating any digital signatures, strong name validation needs to go through the following steps:
- Hash the assembly without the signature
- Decrypt the provided signature to get the original hash
- Valid strong name signatures have the two hash matched
In addition, we also need to validate whether the public key token is hashed from the public key! Why? The digital signature validation verifies that the signer of the assembly owns the key pair, and the public key token validation confirms that token is associated with the public key, thus also belongs to the signer. That is to say, anyone who want to use a token in their assembly’s strong name needs to own the corresponding key pair first. If not, either of the two validations would fail. Strong name signature/validation provides a mechanism for the assembly publishers to claim ownership of a public key token, so that any strong names with that token are reserved for them.