BizTalk | Replacing Strong Name Keys

Background

Strong Names provide .NET Framework assemblies with unique identities. When the .NET Framework loads a strong-named assembly for a referring assembly, it verifies the strong name signature. If the strong name signature of the assembly cannot be verified, the .NET Framework will not load the assembly.

!Do not rely on strong names for security. They provide a unique identity only!

Alternatively in our case, BizTalk assemblies are loaded into the Global Assembly Cache (GAC). In this case, instead of the .NET Framework verifying the assembly identity each time it requires loading, the assembly identity is verified once when installed into the GAC.

Why do we need to strong-name our BizTalk assemblies:

  1. Strong-naming is required if we want to store our assembly in the GAC.
  2. The assembly can be loaded side by side with other versions of the assembly.
  3. The assembly can be referenced and used by other strong-named assemblies.
  4. Strong-naming can prevent assembly conflicts.
  5. Strong-naming prevents spoofing of your code (malicious user can modify your code but cannot re-sign it as you)

    ! Only as long as you keep the private key secure !

Problem Space

One of the big NO NO's when it comes to strong-naming assemblies is, do not add, remove, or change the strong naming key that is used to sign the assembly. Reasoning behind is that by modifying the assembly’s strong-name key you have effectively changed the assembly’s identity. This means any application that uses the assembly will be requiring the assembly with the previous signed public key, thereby .NET Framework will fail verification and or the assembly with that identity wont be found in the GAC.

However, what if you find yourself in the position where:

  1. You have lost the Signing Key that was used to strong-name your assembly.
  2. You have previously password protected your Signing Key but have now forgotten/lost the password.
  3. Your Signing Key has been compromised and you believe a malicious user might wish to modify and re-sign.

In this situation, we need to find a way to regenerate a signing key, and update our BizTalk Applications referencing points so that it knows to look for our assembly with the new identity.

Solution

Every strong-named assembly has a public key that it is identified by, in this case referenced by your BizTalk Application. Each BizTalk Application will reference its dependant assemblies(schemas, maps, orchestrations etc.) through its Bindings of which will also contain the public key for the relevant assemblies. It is this public key that will need to change to the new public key in order to retain the correct assembly identity reference. As part of this verification process, you will also need to make sure the you are referencing the correct version of the assembly.

For Example: Orchestration

 <ModuleRef Name="Application.Orchestrations" Version="1.0.0.0" Culture="neutral" PublicKeyToken="PublicTokenToBeReplaced" FullName="Application.Orchestrations, Version=1.0.0.0, Culture=neutral, PublicKeyToken=PublicTokenToBeReplaced">

For Example: Pipeline

<ReceivePipeline Name="Application.Pipelines.FlatFileReceivePipeline" FullyQualifiedName="Application.Pipelines.FlatFileReceivePipeline, Application.Pipelines, Version=1.0.0.0, Culture=neutral, PublicKeyToken=PublicTokenToBeReplaced" Type="1" TrackingOption="ServiceStartEnd MessageSendReceive PipelineEvents" Description="" />

If you are like me, all my BizTalk Applications are deployed using the BizTalk Deployment Framework allowing me to conduct repeatable deployments without manual configuration and setup between environments. In this case you will need to update your PortBindingsMaster.xml file to replace the public key tokens as shown above.

If deployed manually from scratch, by setting up your ports, orchestrations etc. you will be setting up the new public key link by default. If deploying over the solution, then you will see in your Applications resources two of the same assembly but different PublicKeyToken. You will need to restart host instances (reloads assemblies) and then either update the references to point to the new version of the assembly or you may need to extract the bindings for the application, replace the Public Token, and then import the bindings. Be aware that any secrets held in your bindings will not be extracted and therefore you may need to re-enter these after you import. Once the references to the new assembly are complete, you can remove the old reference.

Retrieving New and Old Public Key from Strong Name Key

BizTalk Server Admin Console

The simplest method of retrieving the current (old) public key is to have a look in the BizTalk Server Admin Console.

  1. Navigate to your Application in BizTalk.
  2. Navigate to Resources.
  3. Find your assembly in the list of resources you are updating.
  4. The Name of the assembly contains the PublicKeyToken.

This method is useful if you have lost the current Strong Name Key, or have forgotten the password.

Strong Name Tool Sn.exe

This method relies on the fact that you still have the current (old) strong name key (if password protected, the password) and have already created the new key.

  1. Load Visual Studio Developer Command Line.

  2. CD to the path that holds your Strong Name Keys

  3. Enter the following command

    sn -p NameOfKey.snk(can also be .pfx) token.snk

    This command extracts the public key from the key pair in the provided strong name and stores it in the new file token.snk

  4. (Password Protected) If you provided a .pfx file, you will be prompted with a password, enter the password that protects the key.

  5. Enter the following command

    sn -t token.snk

    This command displays the public key stored in the new file token.snk

These steps can be followed for both the old key to be replaced and the new key.


Sources

  1. Using Strong Name Signatures | https://learn.microsoft.com/en-us/archive/msdn-magazine/2006/july/clr-inside-out-using-strong-name-signatures

  2. Strong-named assemblies | https://learn.microsoft.com/en-us/dotnet/standard/assembly/strong-named

  3. Global Assembly Cache | https://learn.microsoft.com/en-us/dotnet/framework/app-domains/gac

  4. Creating a Strong-Named BizTalk Assembly | https://learn.microsoft.com/en-us/biztalk/adapters-and-accelerators/accelerator-swift/lesson-2-creating-a-strong-named-biztalk-assembly-for-the-swiftschemas-project

  5. Sn.exe (Strong Name Tool) | https://learn.microsoft.com/en-us/dotnet/framework/tools/sn-exe-strong-name-tool

  6. Deployment Framework for BizTalk Server V5.5 | http://www.tfabraham.com/BTDFDocs/V5_5/

  7. Strong Naming | https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/strong-naming

For the original version of this post see Andrew Wilson's personal blog at BizTalk | Replacing Strong Name Keys