Automatically strong name signing NuGet packages

Edit on GitHub

Some developers prefer to strong name sign their assemblies. Signing them also means that the dependencies that are consumed must be signed. Not all third-party dependencies are signed, though, for example when consuming packages from NuGet. Some are signed, some are unsigned, and the only way to know is when at compile time when we see this:

Referenced assembly does not have a strong name

That’s right: a signed assembly cannot consume an unsigned one. Now what if we really need that dependency but don’t want to lose the fact that we can easily update it using NuGet… Turns out there is a NuGet package for that!

The Assembly Strong Naming Toolkit can be installed into our project, after which we can use the NuGet Package Manager Console to sign referenced assemblies. There is also the .NET Assembly Strong-Name Signer by Werner van Deventer, which provides us with a nice UI as well.

The problem is that the above tools only sign the assemblies once we already consumed the NuGet package. With package restore enabled, that’s pretty annoying as the assemblies will be restored when we don’t have them on our system, thus restoring unsigned assemblies…

NuGet Signature

Based on the .NET Assembly Strong-Name Signer, I decided to create a small utility that can sign all assemblies in a NuGet package and creates a new package out of those. This “signed package” can then be used instead of the original, making sure we can simply consume the package in Visual Studio and be done with it. Here’s some sample code which signs the package “MyPackage” and creates “MyPackage.Signed”:

var signer = new PackageSigner(); signer.SignPackage("MyPackage.1.0.0.nupkg", "MyPackage.Signed.1.0.0.nupkg", "SampleKey.pfx", "password", "MyPackage.Signed");

This is pretty neat, if I may say so, but still requires manual intervention for the packages we consume. Unless the NuGet feed we’re consuming could sign the assemblies in the packages for us?

NuGet Signature meets MyGet Webhooks

Earlier this week, MyGet announced their webhooks feature. After enabling the feature on our feed, we could pipe events, such as “package added”, into software of our own and perform an action based on this event. Such as, signing a package.

MyGet automatically sign NuGet package

Sweet! From the GitHub repository here, download the Web API project and deploy it to Microsoft Azure Websites. I wrote the Web API project with some configuration options, which we can either specify before deploying or through the management dashboard. The application needs these:

  • Signature:KeyFile - path to the PFX file to use when signing (defaults to a sample key file)
  • Signature:KeyFilePassword - private key/password for using the PFX file
  • Signature:PackageIdSuffix - suffix for signed package id's. Can be empty or something like ".Signed"
  • Signature:NuGetFeedUrl - NuGet feed to push signed packages to
  • Signature:NuGetFeedApiKey - API key for pushing packages to the above feed

The configuration in the Microsoft Azure Management Dashboard could look like the this:

Azure Websites

Once that runs, we can configure the web hook on the MyGet side. Be sure to add an HTTP POST hook that posts to <url to your deployed app>/api/sign, and only with the package added event.

MyGet Webhook configuration

From now on, all packages that are added to our feed will be signed when the webhook is triggered. Here’s an example where I pushed several packages to the feed and the NuGet Signature application signed the packages themselves.

NuGet list signed packages

The nice thing is in Visual Studio we can now consume the “.Signed” packages and no longer have to worry about strong name signing.

Thanks to Werner for the .NET Assembly Strong-Name Signer I was able to base this on.

Enjoy!

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment

avatar

5 responses

  1. Avatar for ranjanbd71
    ranjanbd71 April 24th, 2015

    wow, it is so nice. ranjanbd

  2. Avatar for astig07
    astig07 August 16th, 2017

    Hello. I have problem with nuget package which refer some other nuget packages. For example, Selenium.Support which refer to Selenium.WebDriver. When I install Signed versions of this two librarys I recieve error message:
    "ErrorCS0433The type 'RemoteWebDriver' exists in both 'WebDriver, Version=3.5.1.0, Culture=neutral, PublicKeyToken=null' and 'WebDriver, Version=3.5.1.0, Culture=neutral, PublicKeyToken=86042e4d16998b2a'"

    https://uploads.disquscdn.c...

  3. Avatar for astig07
    astig07 August 16th, 2017

    Second question:)

    How works toggles: "Include dependencies?" and "Mirror packages?"

    Maybe I can fix my problem with that toggles?
    I don't understand fully how it works)

  4. Avatar for astig07
    astig07 August 16th, 2017

    Another problem with NWebsec.AspNetCore.Middleware which refer to NWebsec.AspNetCore.Core.
    Now I recieve error:
    "ErrorCS0012The type 'IFluentInterface' is defined in an assembly that is not referenced. You must add a reference to assembly 'NWebsec.AspNetCore.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null'."

  5. Avatar for A Ismaili
    A Ismaili April 8th, 2020

    I found also the following nuget package very useful, that takes care of signing every reference of a project during build. A build target for singing all reference is added automatically since the most recent version. Nuget https://www.nuget.org/packages/Brutal.Dev.StrongNameSigner/

    Project https://github.com/brutaldev/StrongNameSigner