07 October 2012 Assembly, HowTo, Signing Robert Muehsig


Updated on 2016-07-19: Don't do it... it's not helpful and a waste of time.

Huge warning! There might be very very few reasons for Strong Naming, but I can't name you a single one. Try to avoid it at all time. Please read Strong Naming Considered Harmful.


Assemblies zu signieren ist relativ einfach – solange man entsprechend valide Zertifikate für Code Signierung hat. Sobald Assemblies signiert sind haben sie einen “starken Namen” bzw. sind “Strong Named” – diese Begrifflichkeiten liesst man immer wieder.

Am Anfang möchten ich aber mal auf die Frage eingehen:

Warum sollte man Assemblies signieren?

Wer als Web-Entwickler unterwegs ist und auch nur Server-Software schreibt die in einem “kontrolliertem” (d.h. vom Entwickler selbst) Umfeld läuft braucht diesen Prozess eigentlich nicht machen. Auch in vielen Kundenprojekten war dies nie Anforderung und auch nicht wirklich wichtig.

Kniffliger wird es bei Client-Software oder Software, welche auf vielen Kundensystem installiert wird.

Was sind die Vorteile?

Die Assembly hat einen eindeutigen Namen, sodass es auch zu keiner Verwechslung mit anderen Assmblies kommen kann. Wobei ich hier dazu sagen muss: Ich hatte noch nie “versehentlich” eine falsche Assembly geladen.

Wichtigster Punkt: Im Grunde wird sichergestellt, dass die Anwendung keine “verfälschten” oder manipulierten Assemblies lädt. Niemand kann eine Fälschung der System.dll erzeugen und Schad-Code hinzufügen – dies könnte nur der Herausgeber selbst machen. Insbesondere bei Client-Software ist der Punkt des Vertrauens wichtig. Ein böses Szenario könnte sein, dass man eine sehr verbreitete Software angreift indem man Programm dlls austauscht – ohne starken Namen würde das Programm die manipulierten Assemblies laden.

Weitere Punkte sind z.B. hier zu finden.

Was sind die Nachteile?

Es macht initial (etwas) Arbeit die Assemblies zu signieren und das in ein Build-System zu integrieren. Zudem benötigt man ein Zertifikat, welches für Code Signierung gemacht wurde. Ein SLL Zertifikat geht in diesem Fall nicht (für Demo Zwecke kann aber das Visual Studio solch ein Zertifikat generieren.)

Ein wesentlich größerer Nachteil ist allerdings, dass eine Assembly nur signiert werden kann wenn alle anderen benötigten Assemblies auch mit starken Namen ausgestattet sind. Sobald eine Komponente von einem dritt Anbieter nicht mit starkem Namen ausgeliefert wird funktioniert es nicht.

Es gibt einige NuGet Packages, welche Assemblies mit starken Namen ausliefern, allerdings ist das vermutlich nur ein Bruchteil. Wer seine Assemblies also signieren möchte, sollte schauen ob alle Bibliotheken auch von den Herausgebern signiert sind.

Ok… wie funktioniert nun die Signierung über Visual Studio?

In Visual Studio gibt es über die Projekteigenschaften die Einstellung “Signing” – dort kann man ein bestehendes Key File auswählen oder ein neues Test-Zertifikat auswählen.

image

Bei jedem Build wird nun die Assembly signiert.

Negativ bei dieser Variante: Es wird bei jedem Build die Signierung gemacht und jeder Entwickler bräuchte das Key File – was allerdings irgendwie auch nicht gerade Zielführend ist.

Bessere Variante: Über ein Build Server bzw. MSBuild zum Signieren

Über MSBuild kann man auch sehr einfach die Signierung anstoßen:

msbuild myapp.sln /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=mykey.snk

Anstatt dem .snk File kann man auch ein PFX File nehmen – aber Achtung: Ein SSL Zertifikat geht für die Code Signierung nicht! Ansonsten wird beim PFX File allerdings am Anfang noch folgende Fehlermeldung kommen:

Cannot import the following key file: Foobar.pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS_KEY_AE50D88C1F0F7433    StrongNameBlogpost

Über diesen Befehl kann man die PFX importieren:

sn -i companyname.pfx VS_KEY_CONTAINER 

Achtung: Wer ein SSL Zertifkat nimmt bekommt hier keinen Fehler – beim Bauen wird allerdings weiterhin der “Cannot import…” Fehler angezeigt.

Der MSBuild Befehl kann in die meisten Build Systeme einfach aufgerufen werden.

Update: Falls der MSBuild Aufruf mit dem .pfx trotz sn -i ... nicht funktioniert:

Ich hatte das Problem, dass MSBuild auch nach einem erfolgreichen sn -i Aufruf das .pfx nicht kennen wollte. Ein Workaround ist in diesem Fall den KeyContainerName (VS_KEY_CONTAINER...) direkt anzugeben:

msbuild myapp.sln /p:SignAssembly=true /p:AssemblyKeyContainerName="VS_KEY_..."

Wie finde ich heraus ob eine Assembly signiert ist?

sn -vf myassembly.dll/exe 

Als Ergebnis sollte dann: “Assembly ‘…’ is valid”

Wie bekomme ich den Public Key Token heraus?

Auch hier ist der einfachste Weg über das sn Tool:

sn –Tp myassembly.dd/exe

Achtung: Groß- und Kleinschreibung spielt eine Rolle.

Ergebnis sollte sowas sein:

image

Ich find das sn.exe Tool nicht!

Am Besten die Visual Studio 2010 Command Prompt Starten – ansonsten versteckt es sich hier:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\sn.exe

bzw. unter Windows 7:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin\sn.exe


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!