Strong Names Explained

  • Download source - 7 Kb

Introduction

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:

Strong Names Explained_第1张图片

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.

Details

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
  • Authentication

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.

Strong Names Explained_第2张图片

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.

Strong Names Explained_第3张图片

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

Strong Names Explained_第4张图片

Strong Names Explained_第5张图片

add new code group called Test

Strong Names Explained_第6张图片

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

Strong Names Explained_第7张图片

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:

  • It can be very hard to securely associate publisher with his public key when certification authorities are not involved. Publisher must ship his public key by himself and he must ensure that public key is not tampered. Without certification authorities it's impossible to do it securely when our products are distributed over insecure channels and there are no other ways to verify the publisher's public key.
  • There is no way how to revoke public key when the private key has been compromised. As this is easily done in case of certificates (just publish revoked certificates on CRL, Certificate Revocation List) in case of SNs, revocation is a nightmare. Just imagine that you as a junior security engineer has lost USB key with your private key used to sign your assemblies. Then you'll have to call and email your clients with newly signed assemblies, give them your new public key and setup all environments again). There is no automatic way like CRL, everything must be done "by hand".

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:

  • SNs don't require any third party (such as Verisign) to create signatures and manage public keys. Any developer can easily create and manage his keys (see chapter "Generate key pair with sn.exe tool" in my free book ".NET in Samples") without payment to any third party.
  • SNs can avoid network connections and PKI involvement so applications can run and be verified even when network connections are not available.
  • Authenticode certificates are not a part of assembly names and that is why they can't separate publisher's namespaces like SNs do. Do you remember the statement from ECMA in the beginning? That SNs should "deterministically identify" modules and this is the most important reason. So not a security enabler but unique identification is the primary reason for SNs! And Authenticode is not designed for this purpose!

Conclusion

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.

你可能感兴趣的:(Strong Names Explained)