Inżynieria
oprogramowania
Data Protection API
i .NET Framework 2.0
Tomasz Leszczyński
rzmi groznie? Bo jest groznie kiedy firmy two-
warstwa prywatna
rzą oprogramowanie przechowujące pouf-
warstwa publiczna
Local Security
Bne informacje o znaczeniu krytycznym w nie-
CryptoAPI
Authority (LSA)
zaszyfrowanej postaci, klucze i hasła jawnym tekstem
DAPAPI DAPAPI
w pamięci, ba również w rejestrze systemowym i pli-
kach konfiguracyjnych ! Bardziej świadomi włączają
Dane do Dane
zaszyfrowania zaszyfrowane
w funkcjonalność swoich aplikacji mechanizmy szy-
frujące owszem. Cóż jednak z tego jeśli po głębszej
analizie okazuje się iż klucze użyte podczas szyfrowa-
APLIKACJA
nia odnalezć możemy w przestrzeni adresowej działa-
jącego procesu bądz po prostu w kodzie aplikacji? Dla
Rysunek 1. Schemat działania DPAPI
średnio rozgarniętego crakera wystarczającym narzę-
dziem będzie debugger, zrzut pamięci procesu (ang. ny. Użycie takiego algorytmu oznacza iż do zaszyfro-
memory dump) i nieco czasu aby ustalić algorytm szy- wania i odszyfrowania danego bloku danych służy ten
frowania, dokonać ekstrakcji klucza szyfrującego a na- sam klucz. To z kolei oznacza iż zaszyfrowana informa-
stępnie rozszyfrować informację. Poziom bezpieczeń- cja będzie bezpieczna dopóki klucz nie zostanie pozna-
stwa wzrasta gdy aplikacja do wygenerowania klucza ny przez osoby niepowołane. Tak więc warunkiem za-
szyfrującego używa hasła wprowadzanego każdorazo- chowania bezpieczeństwa jest dobre zabezpieczenie
wo przez użytkownika. Takie rozwiązanie nie zawsze kluczy i głównie to właśnie robi za nas DPAPI. Klu-
jest efektywne. Poza tym powstaje możliwość ataku cze zabezpieczane są poprzez ich zaszyfrowanie algo-
mającego na celu przejęcie wprowadzanego hasła rytmem opartym o hasło użytkownika. Domyślnie wy-
za pomocą tych samych technik o których wspomnia- korzystywane jest w tym celu hasło użytkownika sys-
no wcześniej. Jeśli atak taki się powiedzie a użytkownik temu Windows z czego jasno wynika że DPAPI służy
stosował dane hasło również do ochrony innych zaso- do zabezpieczania lokalnych danych użytkownika da-
bów skutki mogą być smutniejsze niż osiołek z Przy- nej stacji roboczej, nie zaś jakiejkolwiek komunikacji po-
gód Kubusia Puchatka . między użytkownikami czy komputerami w sieci. DPA-
PI nie odpowiada również za składowanie i przechowy-
Mocy przybywaj! wanie zaszyfrowanych informacji zadanie to spoczy-
Moc w postaci Data Protection API przybyła dość wa już na barkach programisty. W pewnych sytuacjach
dawno temu bo już razem z systemem operacyjnym możliwość odszyfrowania bloku danych przez inny pro-
Windows 2000. DPAPI rozszerzone zostało w kolej- ces tego samego użytkownika jest niepożądana, dlate-
nych wersjach Windows lecz dostęp z poziomu plat- go też aplikacja podczas szyfrowania może użyć do-
formy .NET możliwy był jedynie poprzez międzyplat- datkowego sekretnego ciągu bajtów zwanego opcjo-
formowe (PInvoke) wywołania kodu niezarządzane- nalną entropią .
go. Sytuację odmieniło nadejście nowej wersji .NET Interakcja aplikacji użytkowej z DPAPI w maksy-
Framework 2.0 posiadającej już wsparcie dla me- malnym skrócie wygląda następująco:
chanizmu DPAPI. W przestrzeni nazw System.Secu-
rity.Cryptography pojawiły się dwie nowe klasy: Pro- " aplikacja A uwierzytelniona w systemie jako
tectedData oraz ProtectedMemory i stała się światłość. użytkownik U wysyła nie zaszyfrowany blok da-
nych do DPAPI;
Ale co to jest& " DPAPI szyfruje blok danych kluczem użytkowni-
Zaczynajmy zatem od początku. DPAPI jest interfej- ka U ;
sem programistycznym umożliwiającym bezpiecz- " DPAPI zwraca aplikacji A zaszyfrowany blok
ne szyfrowanie oraz odszyfrowanie danych w oparciu który odszyfrować będą mogły tylko i wyłącznie
o algorytm szyfrujący wykorzystujący klucz symetrycz- procesy uwierzytelnione jako użytkownik U .
DPAPI zapewnia również cykliczną wymianę kluczy na
Autor jest programistą z siedmioletnim doświadczeniem
nowe co w przypadku sytuacji zdobycia jednego z klu-
zawodowym, współtwórcą grupy deweloperskiej T3
czy przez osoby niepowołane zminimalizuje ryzyko od-
(http://www.t3.com.pl) projektującej systemy informatycz-
szyfrowania wszystkich poufnych danych. Standardowo
ne w oparciu o technologie i narzędzia firmy Microsoft.
Kontakt z autorem: leszczynski@t3.com.pl nowy klucz dla danego użytkownika generowany jest
co trzy miesiące, następnie jest zabezpieczany i skła-
58
www.sdjournal.org
Software Developer s Journal 9/2006
DPAPI i .NET Framework 2.0
Key są najwrażliwszą częścią mechanizmu dlatego też za ich
Listing 1. Użycie klasy ProtectedData
szyfrowanie, składowanie i wymianę odpowiada DPAPI.
// Dane do zaszyfrowania Klucz SessionKey w przeciwieństwie do MasterKey nie jest
byte[] userData = {1, 2, 3, 4, 5, 6}; nigdzie zapisywany jest wykorzystywany jednorazowo pod-
// Dodatkowy ciąg bajtów czas szyfrowania porcji danych a następnie usuwany z pamię-
// (niezbędny pózniej przy odszyfrowywaniu) ci. SessionKey powstaje poprzez policzenie skrótu SHA-1 z połą-
byte[] optionalEntropy = {7, 3, 2, 9, 1}; czenia MasterKey i 16 bajtowej losowej porcji danych. Do zaszy-
Console.WriteLine("Przed zaszyfrowaniem: "); frowanego ciągu bajtów (kryptogramu) dodawana jest owa loso-
Console.WriteLine(System.Text.ASCIIEncoding. wa porcja danych która posłużyła do utworzenia klucza Session-
ASCII.GetChars(userData)); Key umożliwia ona pózniej odtworzenie klucza sesyjnego i od-
// Szyfrujemy ! szyfrowanie informacji. Mechanizm ten zapewnia iż każdorazo-
byte[] protData = ProtectedData.Protect( we zaszyfrowanie tych samych danych, tym samym kluczem
userData, optionalEntropy, MasterKey spowoduje wygenerowanie innego kryptogramu.
DataProtectionScope.CurrentUser); Trzecim z kluczy jest asymetryczny klucz odzyskiwania
Console.WriteLine("Po zaszyfrowaniu: "); RecoveryKey. Klucz ten wykorzystywany jest do tworzenia
Console.WriteLine(System.Text.ASCIIEncoding. tzw. dysku resetowania hasła . W przypadku gdy użytkowniko-
ASCII.GetChars(protData)); wi zdarzy się zapomnieć własnego hasła może za pomocą te-
// Odszyfrowujemy! goż dysku ustanowić nowe hasło. Podczas tworzenia dysku ge-
byte[] unprotData = ProtectedData.Unprotect( nerowana jest para 2048-bitowych kluczy RSA: publiczny oraz
protData, optionalEntropy, prywatny. Za pomocą klucza publicznego szyfrowane jest aktu-
DataProtectionScope.CurrentUser); alne hasło użytkownika a następnie zapisywane w profilu użyt-
Console.WriteLine("Po odszyfrowaniu: "); kownika. Klucz prywatny natomiast jest zapisywany tylko na
Console.WriteLine(System.Text.ASCIIEncoding. dyskietce którą użytkownik powinien następnie fizycznie gdzieś
ASCII.GetChars(unprotData)); ukryć i zabezpieczyć. W momencie wprowadzenia błędnego
hasła użytkownik może wybrać opcję resetuj . System doko-
na próby odszyfrowania hasła zapisanego w profilu za pomocą
dowany w profilu użytkownika. Poza ochroną, wymianą i składo- klucza prywatnego znajdującego się na dyskietce. Jeśli opera-
waniem kluczy DPAPI gwarantuje iż proces szyfrujący dane i za- cja się powiedzie użytkownik może ustanowić nowe hasło.
rządzający kluczami będzie maksymalnie bezpieczny i odseparo-
wany od pozostałych procesów działających w systemie. Idea ta R E K L A M A
zrealizowana została poprzez wykorzystanie usługi Local Secu-
rity Authority (LSA). Usługa LSA jest uruchamiana podczas star-
tu systemu operacyjnego i działa przez cały czas jego pracy pod
szczególną ochroną. LSA odpowiada między innymi za uwierzy-
telnianie użytkowników, zarządzanie zabezpieczeniami systemo-
wymi i generowanie kluczy. W budowie DPAPI możemy zatem
wydzielić dwie warstwy logiczne:
" publiczną udostępniającą interfejs dla programistów i do-
stępną poprzez CryptoAPI (crypt32.dll);
" prywatną niedostępną bezpośrednio dla programistów,
realizującą właściwe zadania kryptograficzne w obrębie
chronionej usługi LSA.
Komunikacja pomiędzy warstwą publiczną a prywatną od-
bywa się poprzez wywołania RPC (Remote Procedure Call).
RPC jest techniką komunikacji międzyprocesowej (IPC in-
terprocess communication) uwzględniającą mechanizmy bez-
pieczeństwa (uwierzytelnianie, autoryzacja).
Jam jest klucznik
Mechanizm DPAPI opiera się o wykorzystanie trzech typów klu-
czy: głównego MasterKey, sesyjnego SessionKey oraz odzy-
skiwania RecoveryKey. MasterKey jest głównym i najważniej-
szym kluczem generowanym przez DPAPI. Stanowi on najważ-
niejszą informację niezbędną do odszyfrowania bloku danych.
Klucz ten nie jest jednak jawnie wykorzystywany przez funk-
cje szyfrujące. Do bezpośredniego szyfrowania bloku danych
używany jest tzw. klucz sesyjny (ang. SessionKey) generowany
z połączenia MasterKey z losową porcją danych. Klucze Master-
Software Developer s Journal 9/2006
Inżynieria
oprogramowania
Hasło
MASTERKEY
użytkownika
SHA1
SHA1
TRIPLE-DES Kod HMAC
Skrót z hasła
użytkownika
Ilość iteracji Zaszyfrowany
PBKDF2
N MASTERKEY
Klucz szyfruj cy
TRIPLE-DES
bazuj cy na haśle
użytkownika
Profil
Zaszyfrowany
użytkownika
HMAC
Rysunek 2. MasterKey
Przepis na danie główne: MasterKey niejsze weryfikowanie integralności odszyfrowanego klucza Ma-
Podstawą MasterKey jest generowany losowo ciąg 512 bitów (64 sterKey czyli po prostu sprawdzenie czy jest on poprawny. Na-
bajty) jak już wspomniano jest on najwrażliwszą częścią me- stępnie za pomocą algorytmu Triple-DES wykorzystującego wy-
chanizmu ponieważ służy do generowania klucza SessionKey znaczony wcześniej klucz bazujący na haśle użytkownika szyfro-
którym bezpośrednio szyfrowane (i odszyfrowywane) są dane. wany jest MasterKey oraz wyliczony dla niego kod HMAC. Za-
Jak zabezpieczany zatem jest sam MasterKey? Otóż wygenero- szyfrowany MasterKey oraz kod HMAC, modyfikator klucza ba-
wany ciąg 512 bitów szyfrowany jest algorytmem PBKDF2 opi- zującego na haśle oraz ilość iteracji użytych do wygenerowania
sywanym w dokumencie PCKS#5 opublikowanym przez firmę tego klucza zapisywane są do pliku i umieszczane w profilu użyt-
RSA. Dokument ten opisuje sposób szyfrowania danych za po- kownika. Te cztery dane w połączeniu z hasłem użytkownika po-
mocą hasła oraz ochrony integralności tychże danych. W skrócie zwalają pózniej na odszyfrowanie klucza MasterKey oraz spraw-
szyfrowanie przebiega następująco: za pomocą algorytmu SHA- dzenie jego integralności.
1 liczony jest skrót (ang. hash) z hasła użytkownika. Następnie
wywoływana jest funkcja szyfrująca PBKDF2 do której przeka- Magazynier
zywany jest skrót hasła, 16 losowo wygenerowanych bajtów sta- Jak już wiemy, DPAPI przechowuje zaszyfrowane klucze Ma-
nowiących tzw. modyfikator klucza (ang. salt) oraz liczba n okre- sterKey w profilu danego użytkownika. Wiemy również iż każ-
ślająca ilość iteracji szyfrowania (domyślna wartość to 4000). dy MasterKey wygasa po pewnym okresie czasu po czym ge-
Funkcja PBKDF2 z podanych danych liczy rekurencyjnie skrót nerowany jest nowy klucz. Pojawia się więc pytanie w jaki spo-
SHA-1 przy czym ilość iteracji wynosi podane wcześniej n. Wie- sób DPAPI odszyfruje dane zaszyfrowane kluczem MasterKey
lokrotne rekurencyjne wyznaczenie skrótu znacznie utrudnia po- który w międzyczasie wygasł i został zastąpiony nowym. Moż-
tencjalny atak metodą siłową (ang. Brute-force). Wyznaczony tak liwe jest to dzięki temu iż DPAPI nie kasuje starych kluczy Ma-
skrót jest tzw. kluczem bazującym na haśle użytkownika. W celu sterKey lecz zapisuje wszystkie w profilu użytkownika. Ponadto
zapewnienia integralności klucza MasterKey liczony jest dla nie- każdemu kluczowi przypisywany jest unikalny identyfikator GU-
go tzw. kod HMAC (Keyed-Hash Message Authentication Code). ID (Globally Unique Identifier). Ten sam numer GUID dołącza-
Kod ten wyznaczany jest poprzez obliczenie skrótu SHA-1 z Ma- ny jest do kryptogramu dzięki czemu DPAPI wie którego klucza
sterKey w połączeniu z hasłem użytkownika. Pozwala on na póz- MasterKey należy użyć dla danego kryptogramu.
60
www.sdjournal.org
Software Developer s Journal 9/2006
DPAPI i .NET Framework 2.0
Nasuwa się również pytanie: jeśli użytkownik zmieni hasło
Listing 2. Użycie klasy ProtectedMemory
to w jaki sposób DPAPI odszyfruje przechowywany MasterKey
(bieżący bądz jeden z poprzednich) który zaszyfrowany został // Dane do zaszyfrowania
starym hasłem ? DPAPI rozwiązuje ten problem poprzez pró- byte[] userData = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
bę wychwycenia momentu modyfikacji hasła. Następuje wtedy 13, 14, 15, 16};
odszyfrowanie wszystkich MasterKey a następnie zaszyfrowa- Console.WriteLine("Przed zaszyfrowaniem: ");
nie ich ponownie już nowym hasłem. Ponadto DPAPI zapisuje Console.WriteLine(System.Text.ASCIIEncoding.
w profilu użytkownika historię haseł użytkownika co pozwala na ASCII.GetChars(userData));
ewentualne odszyfrowanie MasterKey zaszyfrowanego jednym // Szyfrujemy !
z poprzednich haseł. ProtectedMemory.Protect(
Dla użytkowników komputerów będących członkami do- userData, MemoryProtectionScope.SameLogon);
meny DPAPI oferuje dodatkowy mechanizm wykonywania Console.WriteLine("Po zaszyfrowaniu: ");
kopii bezpieczeństwa dla generowanych MasterKey. Mia- Console.WriteLine(System.Text.ASCIIEncoding.
nowicie po wygenerowaniu każdego MasterKey DPAPI ASCII.GetChars(userData));
łączy się z kontrolerem domeny. Po nawiązaniu połączenia // Odszyfrowujemy !
otrzymuje klucz publiczny służący do szyfrowania Master- ProtectedMemory.Unprotect(
Key. Następnie zapisuje w profilu użytkownika dwie wer- userData, MemoryProtectionScope.SameLogon);
sje zaszyfrowanego MasterKey: pierwszą zaszyfrowaną Console.WriteLine("Po odszyfrowaniu: ");
sposobem standardowym za pomocą hasła użytkownika Console.WriteLine(System.Text.ASCIIEncoding.
i drugą zaszyfrowaną kluczem publicznym otrzymanym ASCII.GetChars(userData));
od kontrolera domeny. Kiedy dojdzie do sytuacji w któ-
rej DPAPI nie będzie w stanie odszyfrować danego Ma-
sterKey połączy się z kontrolerem domeny. Po połącze- posiadają więc taki sam rozmiar. Dodatkowe informacje potrzeb-
niu przesłana zostanie kopia MasterKey zaszyfrowana klu- ne do odtworzenia SessionKey generowane są podczas startu
czem publicznym. Kontroler za pomocą klucza prywatne- systemu operacyjnego i przechowywane w pamięci przez DPA-
go odszyfruje MasterKey i prześle go z powrotem do DPA- PI lecz nie są nigdzie zapisywane. Gdybyśmy więc zapisali kryp-
PI. Wszystkie połączenia pomiędzy DPAPI a kontrolerem togram utworzony przez ProtectedMemory np. w pliku, po ponow-
domeny realizowane są za pomocą chronionych wywołań nym starcie systemu operacyjnego jego odszyfrowanie byłoby
RPC. niemożliwe.
W Listingu 1 zaprezentowano bardzo prosty przykład uży-
DPAPI w .NET Framework 2.0 cia klasy ProtectedData (należy pamiętać o wcześniejszym
Wraz z nadejściem .NET Framework 2.0 programiści uzyska- dodaniu w projekcie referencji do pakietu System.Security.dll):
li dostęp do DPAPI za pośrednictwem dwóch klas: ProtectedDa- Dwa pierwsze parametry metod Protect i Unprotect
ta oraz ProtectedMemory. Obydwie klasy posiadają bardzo proste nie wymagają wyjaśnienia, natomiast trzeci parametr typu
interfejsy. Ich wykorzystanie sprowadza się w zasadzie do wy- DataProtectionScope pozwala programiście dodatkowo okre-
woływania dwóch statycznych metod Protect (szyfrowanie da- ślić poziom ochrony danych: dostępne tylko dla proce-
nych) oraz Unprotect (odszyfrowywanie danych). Klasa Protec- sów działających w kontekście tego samego użytkownika
tedData przeznaczona jest do szyfrowania danych które będą (CurrentUser) lub dla wszystkich procesów działających na
pózniej gdzieś zapisywane / składowane, natomiast Protected- danej maszynie (LocalMachine). Kolejny przykład to użycie
Memory służy do szyfrowania tymczasowych danych przetrzymy- klasy ProtectedMemory:
wanych w pamięci. Różnica ta wynika m.in. ze sposobu genero- Należy podkreślić że wielkość bloku danych który za-
wania klucza SessionKey. W przypadku klasy ProtectedData do mierzamy zaszyfrować powinna być wielokrotnością warto-
kryptogramu dołączane są również dodatkowe dane pozwalają- ści 16. Drugi parametr metody Protect i Unprotect pozwala
ce odtworzyć SessionKey i odszyfrować dane. Do kryptogramu na określenie jednego z trzech poziomów ochrony danych:
tworzonego przez ProtectedMemory nie są dołączane żadne do- dostępne dla wszystkich procesów (CrossProcess), dostęp-
datkowe dane. Dane przed zaszyfrowaniem i po zaszyfrowaniu ne tylko dla procesów działających w kontekście tego sa-
mego użytkownika (SameLogon) oraz dostępne tylko dla
procesu który zaszyfrował dane (SameProcess).
W Sieci
Do dzieła!
Cennym zródłem informacji o DPAPI jest na pewno Microsoftowy
DPAPI daje nam do ręki skuteczne narzędzie do zabezpiecza-
MSDN. Poniżej kilka przykładowych linków:
nia poufnych informacji o znaczeniu krytycznym dla bezpieczeń-
" http://msdn.microsoft.com/msdnmag/issues/05/01/
stwa. Wraz z .NET Framework 2.0 programiści zyskali możli-
SecurityBriefs/
wość łatwego i bezproblemowego korzystania z tego narzędzia.
" http://msdn.microsoft.com/library/default.asp?url=/library/
Fakt ten dodatkowo przemawia za tym aby poznać DPAPI i nie-
enus/dnpag2/html/PAGHT000005.asp
wielkim kosztem dokonać wielkich postępów w zakresie zwięk-
" http://msdn.microsoft.com/library/default.asp?url=/library/
szania bezpieczeństwa tworzonych aplikacji. Należy również po-
enus/dnsecure/html/windataprotection-dpapi.asp
wiedzieć otwarcie, że DPAPI nie jest złotym środkiem i reme-
" http://msdn.microsoft.com/msdnmag/issues/03/11/
dium na wszystkie problemy dotyczące bezpieczeństwa szyfro-
protectyourdata/
wanych informacji. n
Software Developer s Journal 9/2006 www.sdjournal.org
61
Wyszukiwarka
Podobne podstrony:
2006 08 Zarządzanie pamięcią w systemach operacyjnych [Inzynieria Oprogramowania]2006 05 Antywzorce w zarządzaniu projektami informatycznymi [Inzynieria Oprogramowania]2006 10 Łączenie kodu C z zarządzanym kodem NET [Inzynieria Oprogramowania]2006 06 Wstęp do Scrum [Inzynieria Oprogramowania]2006 09 Wielozadaniowość w systemach operacyjnych [Inzynieria Oprogramowania]2006 03 XFire w akcji [Inzynieria Oprogramowania]2006 10 Przegląd modeli cyklu życia oprogramowania [Inzynieria Oprogramowania]2006 04 Rozszerzenie wzorca Template [Inzynieria Oprogramowania]2006 07 Jądro systemu operacyjnego [Inzynieria Oprogramowania]Inżynieria oprogramowania IIInżynieria oprogramowania2007 08 UML – modelowanie statycznych aspektów oprogramowania [Inzynieria Oprogramowania]Inżynieria oprogramowania Diagramy ERD,Inżynieria oprogramowania L, operacje w bazie danych biblioteki2007 06 UML – potrzeba standaryzacji notacji [Inzynieria Oprogramowania]2007 11 Extreme Programming i CMMI [Inzynieria Oprogramowania]więcej podobnych podstron