If you have a comment on this topic, contact Aptify Documentation. If you want to return to the Aptify Community Site, please click here.

Recommendations When Signing Assemblies

This topic provides an overview of how to sign assemblies so that they become Strongly Named Assemblies in the Microsoft .NET Framework. While not a requirement, Aptify recommends that all clients strongly name the assemblies for their code-based configurations as described in Aptify's Recommended Approach for Strongly Named Assemblies.

Note that this section is only an overview of a complex topic and cannot be considered to be a comprehensive work on the subject of assembly signing. For in-depth technical information on strongly named assemblies, developers are encouraged to refer to one of the numerous books on the .NET Framework currently in print. For excellent coverage of this topic at a detailed level, Aptify recommends Chapter 3 of Applied Microsoft .NET Framework Programming by Jeffrey Richter (ISBN 0-7356-1422-9).

The recommendations are discussed in the following sections:

Conceptual Overview

The Microsoft .NET Framework allows programmers to create assemblies that are strongly named. Strongly named assemblies are identical in structure to all assemblies in that they use the portable execution (PE) file format, metadata, and other manifest information, and are compiled using the same command line tools or the Visual Studio .NET compiler. A strongly named assembly is differentiated from other assemblies by the fact that it is signed with a component author's private key.

A private/public key combination uniquely identifies the author of an assembly and is extremely useful because it ensures that an assembly actually came from the expected source and has not been tampered with in any way. A strongly named assembly may be uniquely identified even if the assembly is deployed with the same file name as an assembly developed by another author. Strongly named assemblies may be deployed to the Global Assembly Cache (GAC) while other assemblies can only be deployed privately.

Aptify's Strongly Named Assemblies

Assemblies that have been shipped by Aptify have been signed with the Aptify private key and can be verified as coming from the original source. Only the build engineer within Aptify has access to the private key and can use it to sign assemblies. Due to the narrow distribution of the private key, it is very unlikely that code that has not been approved by Aptify's R&D department can be signed and verified. Although Aptify does not currently deploy assemblies to the Global Assembly Cache, the fact that our assemblies are signed provides the option of doing so in the future.

How to Generate Your Own Private Key

Because assemblies from Aptify are signed by a private key that only the Aptify build engineer has access to, the developer must decide when he or she needs to configure the software in a manner that will require a recompile of an assembly. Aptify uses delayed signing, which means that it is possible to recompile the assembly without access to the private key. However, the Common Language Runtime (CLR) will not verify the resulting assembly until it is signed, and the assembly will fail to load in a production environment unless the developer instructs the .NET Framework to skip the verification check.

Developers using delayed signing should use the verification disabling feature during development, but disabling verification is a very unsafe practice in a production environment because all of the benefits of assembly signing are lost. The developer of configuration assemblies must decide whether to turn signing off entirely or to sign the assembly with another private key.

Aptify recommends that a developer of configuration code should sign his or her assemblies with a unique private key for production releases. All configuration work done for clients by Aptify Consulting Services will be signed with a private key specific to Aptify Consulting. The information below is intended for clients who wish to generate their own private key for use in signing components that they will create for production use.

The .NET Framework ships with a command line utility named SN.exe that can be used to generate private keys. If you have Microsoft Visual Studio 2008 installed, the SN.exe utility is located at C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin.

Note that this utility will be in another location for those who only have the Framework SDK installed without Visual Studio; in this case, search your computer for SN.exe.

In addition, Visual Studio users can load a specialized command prompt that sets up the command environment with relevant paths to use the .NET Framework SDK tools.

Follow these steps to use the command prompt to generate a private key:

  1. Load the Visual Studio 2008 Command Prompt.
    • Click Start > All Programs > Microsoft Visual Studio 2008 > Visual Studio Tool > Visual Studio 2008 Command Prompt

  2. Enter this line at the command prompt to generate your own private key

    SN.exe -k C:\PrivateKeyFile.snk

This command line will generate a private key with the name PrivateKeyFile.snk on your hard drive in the path specified. This file actually contains both the private key and the public key. Most organizations will keep the key file on a storage device such as a smart card or a CD rather than on their network. Security of the private key is critical to ensure that it is not used in an unauthorized manner.

Extracting the Public Key From the Private/Public Key File

To use the feature of Delayed Signing, you must extract the public key from the private/public key file generated in the previous step. With delayed signing, the public portion of the key will be used to partially sign an assembly. The SN utility can be used to generate a file containing the public key based on the private/public key pair. The following command line will generate a C:\PublicKey.snk file from C:\PrivateKeyFile.snk:

SN.exe -p C:\PrivateKeyFile.snk C:\PublicKey.snk

Delayed Signing

During the development life cycle, it is useful to use a feature of the .NET Framework that is referred to as Delayed Signing. Since the Private Key is closely guarded in most organizations, not all developers who are writing code for production will have access to the private key during iterative development. The solution is to use the public portion of the key to partially sign an assembly. By doing so, the assembly is strongly named pending an eventual signature from the private key. During the development cycle, the delay signed assembly can be used just like a strongly named assembly by turning verification off for the assembly temporarily. It is even possible to place the assembly into the Global Assembly Cache if verification is turned off.

Perform the following procedures to implement Delayed Signing:

Preparing a Project for Delayed Signing

All of the source code distributed by Aptify is marked for delayed signing. There are two ways to configure a project for delayed signing in Visual Studio:

  1. Use the Signing Properties Dialog to specify that a project should use delayed signing:
    1. Open the project's My Project Properties dialog.
    2. Click the Signing tab.
    3. Select the Sign the assembly option.
    4. Enter the organization's public key in the Choose a strong name key file field.
    5. Select the Delay sign only option.
    6. Save the project.
       
  2. Modify the AssemblyInfo.vb File to manually specify that a project should use delayed signing.
    • Insert the following lines of code into the AssemblyInfo.vb file that exists by default as a standard file of all Visual Studio 2008 projects:

      <Assembly: AssemblyKeyFileAttribute("<PublicKeyFilePath>")>
      <Assembly: AssemblyDelaySign(True)>
    • This code tells the compiler that the assembly will eventually be signed with the private key corresponding to the Public Key file specified in the AssemblyKeyFileAttribute line. In practice, a developer who is working on assemblies that will eventually be signed only needs the public key file to proceed with compilation.

Testing a Delayed Signing Assembly

To test the assembly on a test environment or to install the delay signed assembly into the Global Assembly Cache, it is necessary to turn verification off for the assembly using the following command line from the Visual Studio Command Prompt:

SN.exe -Vr TestAssembly.dll

This line will ensure that verification is not enforced for an assembly named TestAssembly.dll. Note that to turn verification off for all assemblies, a developer can use this command:

*SN –Vr **

 

By default, the Microsoft .NET Framework has verification enabled for all assemblies on load.

 

If a developer does not turn off verification for an assembly, it will fail to load in Aptify with an error message. The exception error logged for this event contains this type of message: Could not load file or assembly...Strong name validation failed.

In the sample application, the SampleCheckOutWizard project is configured to use delayed signing for illustration purposes. If you recompile the wizard's source code, and update the object in Aptify, you will be unable to load the Check Out wizard and will encounter the error shown in figure unless you sign the assembly with the private key provided by Aptify or turn off verification for the assembly. See Strong Name Verification in the Sample Application for details.

Signing a Delayed Signing Assembly with the Private Key

Once the assembly has been fully tested and is ready for installation on a production environment, it is necessary to finalize signing of the partially signed assembly. The individual with access to the private key would execute the following command line to sign an assembly that has been marked for delayed signing:

SN.exe -R TestAssembly.dll C:\PrivateKeyFile.snk

This command line will sign the assembly (TestAssembly.dll) with the private key contained in the C:\PrivateKeyFile.keys file. Note that the private key used to sign the TestAssembly.dll assembly must match the public key used for delayed signing.

Note that the person responsible for signing the project with the private key can also modify the My Project properties to specify the private key and clear the Delay sign only option. Note that when you use this option, the private key is added to the local computer's project directory so the private key holder should be careful not to redistribute the key with the other project files.

Re-Enabling Verification for Assemblies with Verification Disabled

Following the signing of the assembly, it is important to remove the verification exemption that prevents the Common Language Runtime from verifying the assembly. To do so, execute the following command line:

  • SN.exe -Vu TestAssembly.dll

Note that if verification was previously turned off for all assemblies, then a developer can run this command line:

  • SN.exe –Vx

Finally, to review the list of assemblies that have verification turned off, a developer can run this command line:

  • SN.exe -Vl [capital V, lower case L]

Recommended Approach for Strongly Named Assemblies

This section applies the information included above on signing assemblies and presents it as a single process that an organization follow this approach for signing assemblies using an organization-specific private/public key pair. Follow these general steps to implement Aptify's best practice approach:

  1. Generate a private key/public key file. See How to Generate Your Own Private Key for details.
    • In a Visual Studio Command Prompt, run SN.exe -k [private key name and location]

  2. Extract the public key from the private key/public key file. See Extracting the Public Key From the Private/Public Key File.
    • In a Visual Studio Command Prompt, run SN.exe -p [private key name and location] [public key name and location]

  3. Provide the public key to developers and limit access to the private key to a build engineer or one or two other key development staff.
  4. Have developers configure their project to use delayed signing. See Preparing a Project for Delayed Signing for more information.
  5. When testing their compiled assemblies that use delayed signing, developers need to turn off verification for those assemblies before loading them to an Aptify test system.
  6. When the assembly is ready for distribution beyond the developer, the developer provides it to the build engineer (or to someone else who has access to the private key).
  7. The build engineer signs the assembly with the private key and distributes the updated assembly to the appropriate parties.
  8. The assembly's developer re-enables verification for that assembly on his or her system.

Strong Name Verification in the Sample Application

Aptify has signed all of the assemblies that are added to Aptify for the Motor Loaner -application using the sample application's Private Key (named AptifySampleApplication.snk). Aptify has included both the sample application's Private Key and Public Key (named AptifySampleApplication.pbk) with the sample application source code.

However, while all of the compiled assemblies added to Aptify by the sample application installer are strongly named, Aptify has configured the source code for the Check Out Wizard to use Delayed Signing (via the Public Key) for illustration purposes.

This has the following impacts on developers who use the sample application:

  • The sample application is fully functional following the installation of the server components in a test environment.
  • All of the sample application source code projects except for the SampleCheckOutWizard project include the private key (AptifySampleApplication.snk) in the project folder.
  • The SampleCheckOutWizard project includes the public key (AptifySampleApplication.pbk) in the project folder. The SampleCheckOutWizard project is configured for delayed signing, as shown in the following figure.

    Project with Delayed Signing
  • If you recompile the CheckOutWizard assembly, it will use delayed signing. Before adding this recompiled assembly to Aptify, you need to either:
    • Sign the assembly with the AptifySampleApplication.snk key using the SN.exe -R command line option. See Signing a Delayed Signing Assembly with the Private Key for details.
    • Reconfigure the project properties to use the private key, save the project, and  recompile the assembly.

      Project Configured with Private Key Signing
  • Turn off verification for the assembly using the SN.exe -Vr command line option. See Testing a Delayed Signing Assembly for details.

If you do not perform one of the three steps listed above after recompiling the Check Out wizard code and then you add the updated assembly to Aptify, you will be unable to load the Check Out wizard and will encounter an error.

Conclusion

As mentioned previously, one of the most compelling reasons to strongly name your assemblies is the fact that a signed assembly is guaranteed to originate from an individual who has access to the private key. With limited distribution of the private key, it is possible to know with a high degree of certainty that the assembly has not been tampered with. If an unauthorized action occurs related to an assembly (such as someone trying to recompile it who lacks the private key), that assembly will not be verified by the Common Language Runtime and will not be used in a production environment. Aptify uses strongly named assemblies for these reasons, and clients who wish to leverage the same benefits should do so for their own configurations. However, if strongly named assemblies are not required by the policies of an organization, it is permissible to simply remove the delay signing attributes and to proceed with compiles. While the assembly will never be installed in the Global Assembly Cache, it can be privately deployed. However, all of the verification benefits covered in this section will not be available.

 

Copyright © 2014-2017 Aptify - Confidential and Proprietary