WWW Yariv Hammer's Code Site

Tuesday, February 14, 2006

Strong Named Assemblies

This article is one of a series of articles exploring .NET Assemblies.
Exploring .NET Assemblies
Multi-File Assemblies
Strong Named Assemblies
Placing Assemblies in the Global Assembly Cache (GAC)
Administrative Configuration of Applications
The articles are intended for programmers who are using .NET for a while, and wish to know more about .NET assemblies.

Digital Signature is the way to ensure that information was not altered since it was signed.
As developers we distribute our compiled assemblies to our clients. Both the developers and the clients want to make sure that the assemblies are exactly the ones that were first distributed. For example, a malicious programmer can hack into the assembly and alter it to his will. The least we can do is make sure that such thing did not happen before loading the assembly. It would be shameful, for example, if we tried to run an assembly signed by Microsoft, which was changed by someone without our knowledge.

An assembly which is digitally signed is called a Strongly-Named Assembly.

The Process of Signing the Assembly
In order to sign an assembly we need to do the following steps:
1. From the command line, run the line sn -k keys.snk where keys.snk is the name of the file with the keys. This step will generate a file containing a private key and a public key.
2. Open the project you want to sign in VS.NET, and in the AssemblyIbfo file, set the AssemblyKeyFile attribute with the path the snk file.
[assembly: AssemblyKeyFile("..\\..\\keys.snk")]
Alternatively you can do this while linking in the command line:
al /out:MyAssembly.dll /keyfile:keys.snk

After building the assembly if we open the assembly with ildasm, and watch the Manifest, we will be able to see the public key. So the public key is stored inside the assembly file.
The signature appears somewhere at the end of the assembly and cannot be seen in the manifest.

The snk file MUST be kept (in a secure way). Without this file you will not be able to sign the assembly with the same key anymore, and if you already deployed your dll, and there are existing executables referencing to this assembly, those executables will no longer work, unless deployed again with the new signed dll. Access to the snk file by malicious user will allow him or her to make changes to the assembly and sign it on your behalf with the same pair of keys. Be careful.

How Do the Signing Process Work
Now that we know technically how to sign the assembly, lets try to understand what exactly happens, and then try to evaluate the costs of signing.

At the compilation of the dll: The dll IL code is hashed in a well known Hashing algorithm (SHA1). The hashing algorithm produces a word of a constant amount of bits. This word cannot be decrypted back to the assembly code. But, it is statistically almost sure that only the dll produced this code (finding another code that will be hashed to the same hash as the original code is not practical).
After we have the hashed assembly we encrypt it in RSA algorithm using the private key from the snk file. Only the assembly knows the private key, so only the assembly can be encrypted using that key. As we saw before the public key is distributed inside the resulting assembly, so it is known to everybody.

At the compilation of the referencing assembly: For every strong named assembly which is referenced the following process is done: The public key of the referenced assembly is hashed into a 16 bit word, which is called the public key token. You will be able to see this in the Manifest of the assembly after building using ildasm. It will appear under the appropriate reference.

So far we discussed compilation time actions done by the compiler. There are no implications to performance so far.
At run-time: Whenever a Strong Named assembly is loaded, the public key of the dll is first Hashed. The result of the hash should be the same as the public key token of that dll. In order to evaluate the signature, we Hash the dll. This will be the expected result after evaluating the digital signature. We take the digital signature of the dll assembly, and decipher it using RSA algorithm with the public key of the dll. The result should be the same as the hashed dll.
If the comparison failed, we have a problem and we know for sure that the dll was tampered with. The CLR will refuse to load the assembly in that case.

Why Do We Sign Assemblies?
The drawbacks of signing the assemblies are obvious. First, there is an overhead every time we load the assembly. The assembly will be loaded more slowly (Although this should not be too long). Second, we need to look after the snk file or we will loose the private key.

The advantage is that by signing the assemblies we provide reliability to the assembly. The client and you will be sure that the assembly was provided by you (of course the signature has nothing to do with certification for the assembly, and the assembly can still be malicious if you programmed it so).

There are cases where you must sign assemblies: If you place them in the GAC, or if you develop an Enterprise Service (COM+). There are more cases.

It is a best practice to always sign assemblies.

Getting Rid of the Snk File
After generating the snk file (by calling sn -k), we can call
sn -i keys.snk AssemblyKey
Now in the AssemblyInfo file, instead of updating the AssemblyKeyFile attribute (leave empty string), we need to update AssemblyKeyName:
[assembly: AssemblyKeyName("AssemblyKey")]
You can see that we can now use a string ("AssemblyKey" in this example) instead of an snk file.
The file snk file can now be deleted from the computer. We don't need it.

The sn application put the keys in the folder
"C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys" .

Delay Signing
In some scenarios, during development, the signing mechanism is unnecessary and inconvenient. In this case we can prepare the assembly for signing eventually, but for the time being tell the runtime not to validate the signature. When the appropriate time comes, and we wish to deploy the assembly, we will enable the signature validating. This process is called Delay Signing.
In order to delay sign the assembly:
1. Create an snk file: sn -k keys.snk.
2. Create an snk file which contains only the public key: sn -p keys.snk publicKey.snk
3. Go to AssemblyInfo file, and change the AssemblyDelaySign Attribute to true.
[assembly: AssemblyDelaySign(true)]
4. Change the AssemblyKeyFile Attribute to the publicKey.snk file
[assembly: AssemblyKeyFile("..\\..\\public.snk")]
5. Remove the request to validate the assembly: sn -Vr MyAssembly.dll

When we wish to stop the delay signing, and return to regular signing:
1. Re-sign the assembly with the original snk file: sn -R MyAssembly.dll ..\..\keys.snk
2. Enable the signature validation: sn -Vu MyAssembly.dll


At 4:02 AM, December 18, 2012, Blogger Jenice said...

Nice and informative article. Thanks for explaining Strongly-Named Assembly in detail. I was not familiar with it but you have helped me by sharing this article.
electronic signature software

At 2:46 AM, June 27, 2017, Blogger kingrani said...

Flipkart is Offering Cashback Offers Flipkart SBI Cashback Offer You will get upto 75% Discount

Flipkart is Offering Cashback Offers Flipkart AXIS Cashback Offer You will get upto 75% Discount

Flipkart is Offering Cashback Offers Flipkart YES Cashback Offer You will get upto 75% Discount

Flipkart is Offering Cashback Offers Flipkart Phonepe Cashback Offer You will get upto 75% Discount

Flipkart is one of the biggest world wide eCommerce Site flipkart cashback offersso

Flipkart is one of the biggest world wide eCommerce Site Flipkart hdfc offersso


Post a Comment

<< Home

Feel free to use everything here. Add links to my site if you wish.

Do not copy anything to other sites without adding link to here.

All the contents of the site belong to Yariv Hammer.