Introduction

This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.

You can ensure an assembly's identity by signing it. This signing operation employs public-key infrastructure algorithms. Assembly manifests are hashed and signed with a private key. When any assembly is deployed, the hashed value is calculated and compared with the hashed value stored in the assembly. If the runtime hash value matches the hard-coded hash, the installation is allowed to continue.

Note. That the digital signature is found elsewhere in the metadata, in a section that is not included in the manifest. The digital signature of an assembly is just a secure hash of the manifest, which ensures that no one can modify the assembly contents after shipment. The CLR also provides support for embedding digital certificates, Authenticode, into assemblies.

You must use a private key to sign the assembly to create a strong-named assembly. (The strong name is a cryptographically strong identifier provided by the author or publisher of the assembly). The public key is by design incorporated into the assembly when it is signed, so your clients can verify the strong name. A .NET Framework SDK utility, the Strong Name tool (Sn.exe), is used to build strong-name key files.

Strong-name (SN) signatures and Authenticode signatures do not override each other; they coexist. You must be sure that the strong-name signing operation takes place before the Authenticode signing.

You can identify managed code by using Authenticode signatures with strong-name signing. You can consider using both if you already have a security trust structure that depends on Authenticode signatures. The Authenticode signature is stored in a special section of the assembly if an assembly is also signed by using Authenticode. Only the file containing the manifest should be signed when you use Authenticode for multifile assemblies.

Together, SN and Authenticode signatures are nearly impenetrable by hackers. Authenticode signatures warrant that a particular publisher signed an assembly. Authenticode signatures also guarantee that the publisher has not yet revoked the certificate that signed the assembly. However, strong names do not warrant that a signature has not been revoked. Strong names allow you to ensure that the contents of a given assembly have not been tampered with. Therefore, you can make sure that the assembly loaded at runtime is from the same publisher who coded and compiled your program.

For several reasons, the cost of verifying assemblies signed by Authenticode is significantly greater than the cost of verifying a strong-named assembly. Strong-name signing does not involve certificates, but Authenticode does. Similarly, strong-name signing does not depend on a certification hierarchy, but Authenticode does. Remember, an Authenticode signature will make your assembly invalid if you assign a strong-name signature after an Authenticode signature, but the converse is not true.

To summarize, digital signatures and public-key encryption are used for code signing and strong names. After the publisher or author assigns a strong name to an assembly, the strong-name information, which includes a unique public key to the assembly, is stored in the manifest. Each strong-named assembly is digitally signed with a private key corresponding to its public key. This digital signature can be verified by using the public key that is stored in the manifest. You can also further sign an assembly with Authenticode on demand.

Understanding Strong-Named Assemblies and Digital Signatures in .NET

When an application calls a method that is found in another assembly, the runtime tries to locate the assembly by examining binding policy information. The binding policy information is created at compile time and is stored in the application's metadata. Binding is the operation of mapping references to physical assemblies (typically dll's). The policy rules are used to determine how binding is done. An application will be bound to an assembly it was built and tested with, even if a newer version of the assembly is available. Default binding policy is always used unless it is explicitly overridden. Through the use of policy configuration files, binding policy can be altered without having to rebuild the assembly or the application. There are three policy resolution stages that the runtime may goes through before choosing which assembly to load. These stages, in order, are.

Application Policy for Assembly loading

Publisher Policy for Assembly loading

Administrator Policy for Assembly loading

Because the CLR cache is a vital part of the framework, we should delve a bit into the topic. The CLR cache consists of two parts.

From the command prompt in the same directory where MyComponent.dll resides, run gacutil.exe of .NET Framework SDK as shown below.

gacutil /i MyComponent.dll Command

With this command you have placed the assembly in the GAC; and that assembly is said to be a public, shared assembly. It can now be used from other assemblies on the server, regardless of their location on the computer.

The .NET Framework requires developers to specifically identify as partially trusted any strongnamed assembly and components that will be called by mobile code downloaded from the Internet or intranet and any code to which their security policy grants less than full trust.

Without the [assembly:AllowPartiallyTrustedCallers] attribute declaration (a custom attribute of the System.Security.AllowPartiallyTrustedCallersAttribute class) in the assembly configuration file, only fully trusted callers will be able to use the assembly. This attribute makes the assembly callable from any other partially or fully trusted assembly.

The AllowPartiallyTrustedCallers attribute removes the implicit LinkDemand (the permission check conducted on the caller) for the FullTrust permission set that is otherwise automatically placed on each assembly. Following are just some of the .NET Framework assemblies that have the AllowPartiallyTrustedCallers attribute declared.

Refer to the Microsoft .NET Web site for updates to the .NET security framework.

Also note that even with the AllowPartiallyTrustedCallers attribute enabled, assemblies cannot be called by partially trusted code if one of the following security attributes is declared in the code.

Conclusion

Hope this article would have helped you in understanding Signing an Assembly in C#. See other articles on the website on .NET and C#.