.NET Framework 1.1 Security Guidelines - Strong Names
From Guidance Share
- J.D. Meier, Alex Mackman, Michael Dunner, Srinath Vasireddy, Ray Escamilla and Anandha Murukan
Strong Name Your Assemblies
An assembly strong name consists of a text name, a version number, optionally a culture, a public key (which often represents your development organization), and a digital signature. You can see the various components of the strong name by looking into Machine.config and seeing how a strong named assembly is referenced.
The following example shows how the System.Web assembly is referenced in Machine.config. In this example, the assembly attribute shows the text name, version, culture and public key token, which is a shortened form of the public key.
<add assembly="System.Web, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
Whether or not you should strong name an assembly depends on the way in which you intend it to be used. The main reasons for wanting to add a strong name to an assembly include:
- You want to ensure that partially trusted code is not able to call your assembly.
The common language runtime prevents partially trusted code from calling a strong named assembly, by adding link demands for the FullTrust permission set. You can override this behavior by using AllowPartiallyTrustedCallersAttribute (APTCA) although you should do so with caution.
For more information about APTCA, see "APTCA" in Chapter 8, "Code Access Security in Practice." at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh08.asp
- The assembly is designed to be shared among multiple applications.
In this case, the assembly should be installed in the global assembly cache. This requires a strong name. The global assembly cache supports side-by-side versioning which allows different applications to bind to different versions of the same assembly.
- You want to use the strong name as security evidence.
The public key portion of the strong name gives cryptographically strong evidence for code access security. You can use the strong name to uniquely identify the assembly when you configure code access security policy to grant the assembly specific code access permissions. Other forms of cryptographically strong evidence include the Authenticode signature (if you have used X.509 certificates to sign the assembly) and an assembly's hash.
Note Authenticode evidence is not loaded by the ASP.NET host, which means you cannot use it to establish security policy for ASP.NET Web applications.
For more information about evidence types and code access security, see Chapter 8, "Code Access Security in Practice." at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh08.asp
Security Benefits of Strong Names
Strong names provide a number of security advantages in addition to versioning benefits:
- Strong named assemblies are signed with a digital signature. This protects the assembly from modification. Any tampering causes the verification process that occurs at assembly load time to fail. An exception is generated and the assembly is not loaded.
- Strong named assemblies cannot be called by partially trusted code, unless you specifically add AllowPartiallyTrustedCallersAttribute (APTCA.)
Note If you do use APTCA, make sure you read Chapter 8, "Code Access Security in Practice," for additional guidelines to further improve the security of your assemblies.
- Strong names provide cryptographically strong evidence for code access security policy evaluation. This allows administrators to grant permissions to specific assemblies. It also allows developers to use a StrongNameIdentityPermission to restrict which code can call a public member or derive from a non-sealed class.
Note In .NET 2.0, StrongNameIdentityPermission only works for partial trust callers. Any demand, including a link demand, will always succeed for full trust callers regardless of the strong name of the calling code.
Using Strong Names
The .NET Framework includes the Sn.exe utility to help you strong name assemblies. You do not need an X.509 certificate to add a strong name to an assembly.
To strong name an assembly
- Generate the key file in the assembly's project directory by using the following command.
sn.exe -k keypair.snk
- Add an AssemblyKeyFile attribute to Assemblyinfo.cs to reference the generated key file, as shown in the following code sample.
// The keypair file is usually placed in the project directory [assembly: AssemblyKeyFile(@"..\..\keypair.snk")]
Note In .NET 2.0, strong naming and key pair generation is also available through the Signing pane in the Project Designer of the Microsoft Visual Studio 2005 project. For more information, see "How to: Sign an Assembly (Visual Studio)." at http://msdn2.microsoft.com/en-us/library/ms247123.aspx
Delay sign your assemblies
It is good security practice to delay sign your assemblies during application development. This results in the public key being placed in the assembly, which means that it is available as evidence to code access security policy, but the assembly is not signed, and as a result is not yet tamper proof. 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 only accessible by a few trusted personnel. 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.
To create a public key file for delay signing
This procedure is performed by the signing authority to create a public key file that developers can use to delay sign their assemblies.
- Create a key pair for your organization.
sn.exe -k keypair.snk
- Extract the public key from the key pair file.
sn –p keypair.snk publickey.snk
- Secure Keypair.snk, which contains both the private and public keys. For example, put it on a floppy or CD and physically secure it.
- Make Publickey.snk available to all developers. For example, put it on a network share.
To delay sign an assembly
This procedure is performed by developers.
Note In .NET 2.0, the delay signing is also available through the Signing pane in the Project Designer of the Visual Studio 2005 project. For more information, see "How to: Delay Sign an Assembly (Visual Studio)." at http://msdn2.microsoft.com/en-us/library/9fas12zx.aspx
- Add an assembly level attribute to reference the key file that contains only the public key.
// The keypair file is usually placed in the project directory [assembly: AssemblyKeyFile(@"..\..\publickey.snk")]
- Add the following attribute to indicate delay signing.
- The delay signing process and the absence of an assembly signature means that the assembly will fail verification at load time. To work around this, use the following commands on development and test computers.
- To disable verification for a specific assembly, use the following command.
sn -Vr assembly.dll
- To disable verification for all assemblies with a particular public key, use the following command.
sn -Vr *,publickeytoken
- To extract the public key and key token (a truncated hash of the public key), use the following command.
sn -Tp assembly.dll
Note Use a capital –T switch.
- To fully complete the signing process and create a digital signature to make the assembly tamper proof, execute the following command. This requires the private key and as a result the operation is normally performed as part of the formal build/release process.
sn -r assembly.dll keypair.snk
Authenticode your assemblies
Authenticode and strong names provide two different ways to digitally sign an assembly. Authenticode enables you to sign an assembly using an X.509 certificate. To do so, you use the SignCode.msi utility, which adds the public key part of a full X.509 certificate to the assembly. This ensures trust through certificate chains and certificate authorities. With Authenticode (unlike strong names,) the implementation of publisher trust is complex and involves network communication during the verification of publisher identity.
Authenticode signatures and strong names were developed to solve separate problems and you should not confuse them. Specifically:
- A strong name uniquely identifies an assembly.
- An Authenticode signature uniquely identifies a code publisher.
Authenticode signatures should be used for mobile code, such as controls and executables downloaded via Internet Explorer, to provide publisher trust and integrity.
You can configure code access security (CAS) policy using both strong names and Authenticode signatures in order to grant permissions to specific assemblies. However, the Publisher evidence object, obtained from an Authenticode signature is only created by the Internet Explorer host and not by the ASP.NET host. Therefore, on the server side, you cannot use an Authenticode signature to identify a specific assembly (through a code group.) Use strong names instead.