Nie wiem czy jest polski odpowiednik strong-named(SN) wiec będę używał nazwy angielskiej albo skrótu SN. Do zrozumienia tego wpisu niezbędna jest podstawowa wiedza o asymetrycznych algorytmach szyfrowania (RSA), podpisie cyfrowym , kluczu prywatnym, publicznym oraz zasadzie działania funkcji haszującej. Nie będę tego omawiał w poście, zachęcam więc do zapoznania się na własną rękę jeśli któreś z tych pojęć jest niezrozumiałe.
SN to przede wszystkim sposób na unikalne identyfikowanie bibliotek. Przed pojawieniem się SN trudno było odróżnić dwie różne biblioteki o tej samej nazwie. Kiedyś wszystkie biblioteki składowane były w jednym folderze co powodowało tzw. DLL HELL. W końcu może zdarzyć się, że dwie różne firmy wydają biblioteki o takiej samej nazwie. Inny scenariusz to biblioteki o tej samej nazwie ale o różnych wersjach. Na przykład aplikacja A może być kompatybilna z wersją wyłącznie 1.00 a program B wyłącznie z wersją 2.00. Mowa oczywiście tutaj o bibliotekach wdrażanych globalnie czyli np. GAC.
Kolejna korzyść z SN to bezpieczeństwo. O tym z pewnością powstaną następne wpisy ale spróbuje to naszkicować dzisiaj. Przede wszystkim biblioteka strong-named jest podpisana i dzięki temu mamy pewność, że pochodzi ona od konkretnego producenta. Podpis gwarantuje integralność biblioteki – przed załadowaniem jej sprawdzana jest suma kontrolna. Jeśli ktoś ją po drodze zmodyfikować (np. hacker) wtedy będzie to wykryte podczas jej ładowania. Dzięki temu można również określić różne przywileje wykonania kodu w zależności kto jest właścicielem biblioteki.
Wiemy, już po co wprowadzano SN (łatwa identyfikacja oraz bezpieczeństwo). Jak wspomniałem ważną role w SN stanowią algorytmy szyfrowania asymetrycznego oraz funkcje haszujące. Cztery atrybuty identyfikują unikalnie bibliotekę:
-
Nazwa biblioteki (bez rozszerzenia).
-
Wersja
-
Culture (np. en-US).
-
Hash klucza publicznego. Sam klucz publiczny jest bardzo długi dlatego stosuje się po prostu jego hash.
Przykład:
MyLib, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=d375d1c535425e6
Aby biblioteka była SN należy wykonać następujące kroki:
-
Wygenerować dwa klucze: publiczny oraz prywatny. To one w skali globalnej identyfikują biblioteki. Powinny być unikalne dla każdej organizacji\firmy.
-
Klucz publiczny będzie umieszczony w bibliotece. W końcu użytkownik końcowy musi jakoś odszyfrować potem pakiet. W kryptografii klucz publiczny otrzymuje odbiorca a prywatny jest poufny i ma do niego dostęp tylko nadawca (w tym przypadku firma\organizacja). Po umieszczeniu klucza publicznego, biblioteka jest haszowana za pomocą algorytmu SHA-1. Następnie hash jest szyfrowany algorytmem asymetrycznym RSA za pomocą klucza prywatnego. Zaszyfrowany hash stanowi podpis biblioteki. Oczywiście jest to skrót myślowy ponieważ w rzeczywistości szyfrowane są specyficzne pliki ale aby zrozumieć sens SN wystarczy wiedzieć, że wygenerowany zostanie podpis cyfrowy czyli zaszyfrowanie hash’a biblioteki.
-
Wygenerowany w kroku 2 podpis jest umieszczany również w bibliotece.
Następnie gdy użytkownik próbuje odczytać bibliotekę (wywołać jakąś metodę):
-
Załadowanie klucza publicznego.
-
Obliczenie hash’u biblioteki.
-
Załadowanie podpisu. Odszyfrowanie go za pomocą klucza publicznego.
-
Wynik z punktu 3 porównywany jest z hash’em obliczonym w punkcie 2. Jeśli są one takie same to znaczy, że biblioteka nie została podmieniona. Gwarantuje to integralność danych.
Na tym etapie, wiemy, już co to znaczy dostarczyć bibliotekę strong-named. Pytanie pozostaje, jak to zrobić?
Istnieje kilka sposobów. Jednym z nich jest użycie komendy SN w wierszu poleceń. Umożliwia to wygenerowanie pary kluczy a nawet wyodrębnienie z pary tylko klucza publicznego.
Osobiście nie lubię wiersza poleceń i dlatego w poście pokażę jak to zrobić z poziomu Visual Studio. Wystarczy przejść do właściwości projektu a następnie wybrać zakładkę Signing:
Następny zaznaczamy checkbox Sign the assembly, klikany new i wpisujemy nasze hasło:
Po skompilowaniu biblioteka będzie zawierała Strong Name. Można się o tym przekonać dołączając ją do jakiegoś projektu i sprawdzając właściwość StrongName:
Na zakończenie jeszcze kilka słów o integralności. Załóżmy, że ktoś zmienił zawartość biblioteki, doczepiając jakiś złośliwy kod. Dzięki SN wykryjemy to podczas ładowania ponieważ w takim przypadku hash będzie inny. Jeśli ktoś zmieni klucz publiczny również wykryjemy to ponieważ hash został obliczony na bibliotece zawierającej w sobie już klucz publiczny. Mechanizm gwarantuje nam, że dostaniemy identyczną zawartość, która została podpisana przez wydawcę. W następnym poście napiszę o Delay Singing a potem o sprawach bezpieczeństwa (konkretnie o nadawaniu pozwoleń).
Fajne!
Zamień wszystkie wystąpienia asynchroniczne/asynchronicznych na asymetryczne/asymetrycznych itp.
“Strong-named dll” = “podpisana biblitoeka”, tak mi się wydaje
@Tadeusz:
Masz racje. Za duzo ostatnio o wielowatkowosci pisalem i stad te problemy. Dzieki za uwage.
@Maciej:
Podejrzewam ze wiecej programistom powie nazwa strong named 🙂
Odnośnie bezpieczeństwa, ostatni akapit artykułu: http://blog.milosierny.net/2010/03/18/na-czym-polega-podpisywanie-assembly/
Dobry artykuł. Właśnie przerabiam ten temat. Czekam z niecierpliwością na więcej!