Still Strong-Naming your Assemblies? You do know it’s 2016, right?

We Want You To Stop Strong-Naming Assemblies

Last Updated 02/04/2016

For far to long, Strong-Named Assemblies have been a huge rock in the shoe of 3rd party library developers, but people: it’s 2016, so why are you still using it?

How it all started…

The year was 2002 (or so I believe!), Microsoft had just released the .NET Framework, and one of the main enterprise focused features was the ability to sign an assembly with a strong-name.

Back then, Strong-Named Assemblies had some great advantages, as indicated in this MSDN article:

  • You want to enable your assemblies to be referenced by strong-named assemblies, or you want to give friend access to your assemblies from other strong-named assemblies.
  • An app needs access to different versions of the same assembly. This means you need different versions of an assembly to load side by side in the same app domain without conflict. For example, if different extensions of an API exist in assemblies that have the same simple name, strong-naming provides a unique identity for each version of the assembly.
  • You do not want to negatively affect performance of apps using your assembly, so you want the assembly to be domain neutral. This requires strong-naming because a domain-neutral assembly must be installed in the global assembly cache.
  • When you want to centralize servicing for your app by applying publisher policy, which means the assembly must be installed in the global assembly cache.

So strong-named assemblies are uniquely identified, which is a good thing, until it starts to work against you…

Let’s look at a real example: a few years back, JSON.net was actually a strongly-signed assembly. Now let’s assume we have a project that depends on “LibraryA” and “LibraryB”, and each of these require a different version of JSON.net.

Before Assembly Binding Redirection

If you build the project as it currently is, there will be a conflict as you can only have a single version of JSON.net on the output folder, but the libraries require different versions…

To fix this issue, .NET provided a mechanism called Assembly Binding Redirection to ensure that only one specific assembly would be used, regardless of the required version.

After Assembly Binding Redirection

In comes Silverlight and Windows Phone

Unfortunately, neither Silverlight nor Windows Phone support Assembly Binding Redirection… and that is where the true problems started.

There are quite a few threads around this issue over the internet, and in the end, a lot of 3rd party library developers just decided to stop strong-naming their assemblies!

Others, followed the advice of the MSDN article I pointed above:

If you are an open-source developer and you want the identity benefits of a strong-named assembly, consider checking in the private key associated with an assembly into your source control system.

Obviously, for this to work you would have to build your own versions of your project dependencies… and let’s be honest here: that will eventually be more of a problem that a solution.

A few years ago, I personally felt this pain while developing a Windows Phone app, and so I went to the Windows Phone Developers UserVoice website and requested the support for Assembly Binding Redirection on Windows Phone… almost a year after the request, I got an update indicating it was “on the backlog”, and seems it has stayed like that till now…

If it is such a bad thing, why are people still doing it?

Developers seem to have the wrong notion that they should strong-name their assemblies as a security feature, but this could not be further away from the truth!

Granted, that does provide a basic insurance that an assembly hasn’t been tampered/altered, but in any case one can always use binding redirection (when available) to bypass the whole thing, so that is just a lame excuse to not buy a proper Code Signing Certificate and apply Authenticode to the assembly (which will prevent tampering AND impersonation, the right way!).

What about the Universal Windows Platform?

Unfortunately, as far as I know there is no support for Assembly Binding Redirection in UWP

A couple of weeks ago, Microsoft open-sourced the XAML Behaviors and guess what? Yes you guessed correctly: they strongly-signed it!

Fortunately, after a long debate on that same thread, they realized that it made no sense to do that, and removed the strong-name signing on the latest version!

Bottom line

With this article I tried to make the point that Strong-Named Assemblies are just legacy of the “old” .NET Framework days, and have no place in the modern Universal Windows Platform.

Hopefully, 3rd party developers will continuously provide non-strongly-named assemblies which will make a lot of developers happy.

Update 02/04/2016

David Kean, Microsoft developer on the C#/VB languages team, was kind enough to add his thoughts to this article comments, and it seems that any Core CLR or .NET Native based platform (like UWP) will…

…allow later versions of an assembly (ie 2.0.0.0) to satisfy refs to an earlier version (ie 1.0.0.0). You put the higher version in the package, and the runtime will gladly use it.

So it seems that Microsoft did in fact provide a great solution for the strong naming binding redirection issue: they will do it automatically, at least for the most recent platforms! šŸ™‚

  • Security!

  • David Kean

    While you are correct that original versions of Windows Phone 7.x (which is based on Compat Framework), didn’t support binding redirects – and needed them, Windows Phone 8.x (CoreCLR), Silverlight (CoreCLR), and UWP (CoreCLR/.NET Native) don’t need it. Their binding policy is not as strict as the .NET Framework; they allow later versions of an assembly (ie 2.0.0.0) to satisfy refs to an earlier version (ie 1.0.0.0). You put the higher version in the package, and the runtime will gladly use it.

    There still are a few reasons for strong naming an assembly, and if you need to, there there are new options for reducing the pain, including (OSS signing [https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/oss-signing.md] and automatic binding redirects)

    I’ve written up some guidance here about it and why we continue to strong name: https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/strong-name-signing.md.

    • Wow, I did not know that David, thanks for pointing out on that! I do have a question: what about PCL libraries? What happens if they reference a strongly signed assembly? Will it still be able to use a later version of the assembly? I’ll make sure to update on this post to reflect your comments! šŸ™‚

      • David Kean

        The platform decides the policy, so a portable library running on the platforms I call out above have the same behavior as a normal dll. In fact, in UWP & .NET Core, there’s no difference between a “PCL” and a normal assembly, they are exactly the same.

  • I just had to upgrade from Rx 2.2.5 to System.Reactive 3.0, and they changed the strong name key..
    Assembly binding redirects won’t help in this case, so “but in any case one can always use binding redirection (when available) to bypass the whole thing” seems to be invalid.
    Neither did plugging AssemblyResolve event. (Get a manifest mismatch error).

    I ended up recompiling all packages dependent on Rx; now im in maintenance hell šŸ™‚