Strong Name (further referred to as "SN") is a technology introduced with the .NET platform and it brings many possibilities into .NET applications. But many .NET developers still see Strong Names as security enablers (which is very wrong!) and not as a technology uniquely identifying assemblies. There is a lot of misunderstanding about SNs (as we could see in the article "Building Security Awareness in .NET Assemblies : Part 3 - Learn to break Strong Name .NET Assemblies ") and this article attempts to clear those up. Now let's see what SNs are, what we can use them for and how they work.
Strong Name is a technology based on cryptographic principles, primary digital signatures; basic idea is presented in the figure below:
At the heart of digital signatures is asymmetric cryptography (RSA, EL Gamal), together with hashing functions (MD5, SHA). So what happens when we want to sign any data? I'll try to explain what happens in the figure above.
First we must get a public/private key pair (from our administrator, certification authority, bank, application etc.) that we will use for encryption/decryption. Then DATA (term DATA represents general data we want to sign) is taken and run through some hashing algorithm (like MD5 or SHA - however, MD5 is not recommended) and hash of DATA is produced. The hash is encrypted by private key of user A and attached to plaintext data. The DATA and attached signature are sent to user B who takes public key of user A and decrypts attached signature where hash of DATA is stored and encrypted. Finally user B runs DATA through the same hashing algorithm as user A and if both hashes are the same then user B can be pretty sure that the DATA has not been tampered with and also identity of user A is proven. But this is a naive scenario because it's hard to securely deliver public keys over insecure communication channels like Internet. That is why certificates were introduced but I will not cover it here because certificates aren't used in SNs and delivery of public key is a matter of publisher's policy (maybe I can cover distribution of public keys, certificates and certification authorities in another article). Now let's assume that public key was delivered to user B securely.
This process is used in the creation of SN for .NET applications. You can translate term DATA as assemblies and apply the same steps to them when SNs are used. But what is the purpose and usage of this SN technology? Simple - there is the only one reason – to uniquely identify each assembly. See section 24.3.3.4 of CLI ECMA specification where SNs are defined:
This header entry points to the strong name hash for an image that can be used to deterministically identify a module from a referencing point (Section 6.2.1.3).
SNs are not any security enhancement; they enable unique identification and side-by-side code execution.
Now we know that SNs are not security enablers. Where to use them then? We can see two scenarios where SNs can be used:
Versioning solves known problem called as "DLL hell". Signed assemblies are unique and SN solves problem with namespace collisions (developers can distribute their assemblies even with the same file names as shown of figure below). Assemblies signed with SNs are uniquely identified and are protected and stored in different spaces.
In addition to collision protection, SN should help developers to uniquely identify versions of their .NET assemblies.
That is why when developers want to use GAC (Global Assembly Cache) assemblies must be signed to separate each publisher's namespace and to separate each version.
The second important feature of Strong Names is authentication; a process where we want to ensure ourselves about the code's origin. This can be used in many situations, such as assigning higher permissions for chosen publishers (as will be shown later) or ensuring that code is provided by a specific supplier.
It has been shown that signatures and public keys can be easily removed from assemblies. Yes, that is right but it is correct behavior even when we use digital signatures in emails or anywhere else! Let's see how it works!
We can use some analogy from our real life. Let's assume you are a boss of your company and you are sending an email to your employees where new prices of your products are proposed. This email is a plaintext and you use some non-trusted outsourcing mailing services. Your communication can be easily monitored and your email can be easily accessed by unauthorized persons who can change its content, for instance your prices proposed in email.
How to solve that? The answer is cryptography, again digital signatures that you can use to authenticate to your employees and to verify content of your email. Simply you have to add a digital signature to your email and then require your employees will trust just verified emails that have your valid digital signature. Let's assume that all PKI infrastructure is set up and working correctly. Now, when an intruder removes the digital signature from your email, his employees will not trust them because they can't be verified and application will alert users about this insecure state.
The same situation is when SNs are used. You can remove SNs from assemblies , but this makes no sense because just as in the case of emails, assemblies without SNs can't be trusted when environment is set up to require those digital signatures or SNs.
This is also related to another very important point in .NET – Code Groups & Policy Levels. As in the case of emails, when PKI is setup in a company and security policy is defined that employees can't trust and verify emails which are not signed or where the encrypted hash value is different from hashed plaintext content. The same can be done with .NET Framework using the .NET Configuration tool on each machine or by group policy for large networks.
This tool provides configuration options for .NET Framework including Runtime Security where policy levels and code groups can be set. Policy levels work on intersection principle as shown in the figure below
Code groups (inside of those policy levels) provide permission sets for applications that belong to them according to their evidence (origin, publisher, strong name etc.). The assembly will get those permissions based on the intersection of code groups from each policy level applicable to it. This is a very important improvement in security architecture and improves the traditional Windows security model that is process centric (see figure below).
.NET introduces Code Access Security (CAS) which is used to identify the origin of code and assign to it specific restrictions and then make security policy more granular and protecting against attacks such as luring attacks.
However my intention isn't to describe CAS or Windows security internals (I can write about it in other articles) but show SN principles. Let's move back to it!
Now we can move to the second use for SN - administrators and developers can use SNs together with code groups to provide assemblies with higher permissions (not the default ones that assembly will acquire according to default .NET Framework settings). Let's see an example! I must point out that this is just a simplified example how SN can identify publisher, this is NOT a way to obey CLR security or how to use it in enterprise environment. That is why please try to understand the example as a general principle available with SNs but NOT as a design pattern! Usage of SNs as authentication is a more complex problem and there are many non-trivial issues when SNs are involved. But it's out of scope of this article, so now back to the sample!
Take my sample Windows Forms project and rebuild it and put .exe file on any share on your LAN. Then try to start this application from this share and click on button – what happens? A security exception is raised because application doesn't have enough privileges.
Now go to .NET Configuration tool and add a new code group
add new code group called Test
and in the second dialog choose Strong name, click on Import button and locate the .exe file in Debug folder of project folder and finally assign full trust for this application
Now you have created a new code group containing just your sample application. Now go to your network share and try to start sample application again. And it works! Why? Because it belongs to our new code group Test with full trust permissions.
Now remove SN from sample application (as described in his article or just simply remove attribute [assembly: AssemblyKeyFile("KeyFile.snk")] from AssemblyInfo.cs file), recompile and publish it on share. Try to run it and what happens? It's not working! Why? Because assembly can't show this strong name evidence and it belongs to the default code group (with limited privileges) now.
It's not surprising, nothing special, no magic – just correct usage of Strong Name technology. SNs are easy and powerful but we have to understand how and where to use them. That is why I want to outline some "issues" that are connected with SNs that will present all capabilities that we can expect from SNs.
So what are the weaknesses of SNs? First we have to realize that SNs are a lightweight version of Authenticode and they provide fast and easily used technology to get enterprise features like versioning and authentication. But this ease of use must be paid by something and here goes a list of disadvantages:
Authenticode can be considered as more powerful from an enterprise and architectural perspective. So why not use Authenticode instead of SNs? Here are the reasons:
I hope this helps you understand the strong name technology in the .NET Framework, and helped you see that it is very powerful, but with defined limits. It is a technology that should be used appropriately.
With SNs we can uniquely identify an assembly and run side-by-side our assemblies. Security scenarios are not recommended to be used with Strong Names (even when it's supported by .NET Framework), just in case you are advanced in security and working with certificates and key management. There are many design patterns on how to use Strong Names and all this depends on application architecture, client requirements and infrastructure settings (Active Directory, PKI etc.).
There could be much more written about it (like usage of SNs in large companies, problems with key distribution, etc.), but this was not intended for this article, it was just a reaction to some misinterpretation of this technology and the article is intended to put it right.