.NET 2.0 Security Guidelines - Strong Names

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe


Evaluate whether you need strong names

Evaluate Whether You Need Strong Names From a security point of view, there are no reasons not to use strong names. However, they can make versioning more complicated. For example, if you fix a bug in a strong named assembly and increment its strong name version number, you have to either rebuild everything that depends on that assembly or deploy publisher policy with the assembly.

The following are the most common reasons to sign an assembly with a strong name:

  • You need to add your assembly to the global assembly cache. If you want your assembly to be shared among multiple applications, then you should add it to the global assembly cache. To add your assembly to the global assembly cache, you need to give it a strong name. Adding an assembly to the global assembly cache ensures that your assembly runs with full trust.
  • You want to prevent partial trust callers. The CLR prevents partially trusted code from calling a strong named assembly by adding a link demand for the Full Trust permission set. You can override this behavior by using AllowPartiallyTrustedCallersAttribute (APTCA), although you should do so only if you are fully aware of the issues and after careful code review. For more information, see the section, "APTCA," in this document.
  • You want cryptographically strong evidence for security policy evaluation. Strong names provide cryptographically strong evidence for code access security policy evaluation. This allows administrators to grant permissions to specific assemblies. For example, the public key component of a strong name is often used to represent a particular organization. You could create policy that only allows code from designated organizations to run on your computers.

Do not expect strong names to make your assembly tamper proof

By adding a strong name to an assembly, you ensure that it cannot be modified and still retain your strong name signature. The strong name does not make your assembly tamper proof. It is still possible to remove a strong name, modify the IL code, and then reapply a different strong name.

However, an attacker cannot recreate a valid signature from your original publisher's key unless your publisher's private key has been compromised. Because the key is part of the strong name identity, if an attacker strips a strong name signature, signs the code, and then installs the code in the global assembly cache, the code will have a different identity. Any callers looking for the original assembly will not bind to an assembly signed with a different private key. Strong names prevent this type of substitution attack.

Note Both Authenticode and strong name signing ensure that if the signed code is tampered with, the signature will be invalidated. However, neither technology prevents an attacker from stripping off the signature, modifying the IL, and signing the code with the attacker's key.

Use delay signing appropriately

You should consider using delay signing when there are more than a few developers on your projects and/or you have a daily build process that allows you to easily sign assemblies generated from your daily build. Even if you do not meet either of these conditions, you should consider using delay signing if your private key is extremely sensitive; for example, because you have made trust decisions based on your private key across the thousands of desktops in your enterprise.

Delay signing places the public key in the assembly, which means that it is available as evidence to code access security policy, but the assembly is not signed. From a security perspective, delay signing has two main advantages:

  • The private key used to sign the assembly and create its digital signature is held securely in a central location. The key is accessible to only a few trusted individuals. As a result, the chance of the private key being compromised is significantly reduced.
  • A single public key, which can be used to represent the development organization or publisher of the software, is used by all members of the development team, instead of each developer using his or her own public, private key pair, typically generated by the sn -k command.

Use .pfx files to protect your private key if you do not use delay signing

If you do not use delay-signing, use password protected .pfx files to protect your private key. Visual Studio .NET 2005 adds support for .pfx files, which makes this very convenient. This approach is more appropriate for small to medium sized projects. If you previously passed around or had access to .snk files that included a private key, you should consider using .pfx files instead.

Do not depend on strong name identity permissions in full trust scenarios

If you protect your code with a link demand for a StrongNameIdentityPermission to restrict the code that can call your code, be aware that this only works for partial trust callers. The link demand will always succeed for full trust callers, regardless of the strong name of the calling code.

In .NET Framework 2.0, any fully trusted assembly will satisfy any demand, including a link demand for an identity permission that the assembly does not satisfy. In .NET Framework 1.0, this did not happen automatically. However, a fully trusted assembly could simply call Assembly.Load, supplying as evidence the strong name it wants to satisfy, or, alternatively, it could turn code access security off.

The only protection against fully trusted code is to put it in a separate process and run that process with a restricted token so that its limits are enforced by the operating system. This applies whether code marks its interfaces as internal or private, or places link demands for StrongNameIdentityPermission on them.

The following code sample shows a method decorated with a link demand for a specific StrongNameIdentityPermission.

public sealed class Utility
 // Although SomeOperation() is a public method, the following 
 // permission demand means that it can only be called by partial trust 
 // assemblies with the specified public key OR by any fully trusted code. 
 public static void SomeOperation() {}
Personal tools