Omówienie szyfrowania, podpisów cyfrowych i algorytmów wyznaczania wartości skrótu na .NET

Ten artykuł zawiera omówienie metod i praktyk szyfrowania obsługiwanych przez platformę .NET, w tym ClickOnce manifestów.

Wprowadzenie do kryptografii

Sieci publiczne, takie jak Internet, nie zapewniają bezpiecznego środka komunikacji między jednostkami. Komunikacja za pośrednictwem takich sieci jest podatna na odczytywanie lub nawet modyfikację przez nieautoryzowane osoby trzecie. Kryptografia pomaga chronić dane przed wyświetlaniem, zapewnia sposoby wykrywania, czy dane zostały zmodyfikowane, i pomaga zapewnić bezpieczny sposób komunikacji za pośrednictwem niezabezpieczonych kanałów. Na przykład dane mogą być szyfrowane przy użyciu algorytmu kryptograficznego, przesyłane w stanie zaszyfrowanym, a później odszyfrowywany przez zamierzony. Jeśli strona trzecia przechwyci zaszyfrowane dane, będzie to trudne do odszyfrowania.

Na platformie .NET klasy w przestrzeni nazw System.Security.Cryptography zarządzają wieloma szczegółami kryptografii. Niektóre są otokami dla implementacji systemu operacyjnego, a inne są wyłącznie zarządzanymi implementacjami. Nie musisz być ekspertem w zakresie kryptografii, aby korzystać z tych klas. Podczas tworzenia nowego wystąpienia jednej z klas algorytmów szyfrowania klucze są automatycznie generowane w celu ułatwienia użycia, a właściwości domyślne są tak bezpieczne, jak to możliwe.

Kryptograficzne typy pierwotne

W typowej sytuacji, w której używana jest kryptografia, dwie strony (Alice i Bob) komunikują się za pośrednictwem niezabezpieczonych kanałów. Alice i Bob chcą mieć pewność, że ich komunikacja pozostanie niezrozumiała dla każdego, kto może nasłuchiwać. Ponadto, ponieważ Alice i Bob znajdują się w lokalizacjach zdalnych, Alice musi upewnić się, że informacje, które otrzymuje od Boba, nie zostały zmodyfikowane przez kogoś podczas transmisji. Ponadto musi się upewnić, że informacje tak naprawdę pochodzą od Boba, a nie od osoby, która personifikuje Boba.

Kryptografia służy do osiągnięcia następujących celów:

  • Poufność: w celu ochrony tożsamości lub danych użytkownika przed ich odczytem.

  • Integralność danych: w celu ochrony danych przed zmianą.

  • Uwierzytelnianie: w celu upewnienia się, że dane pochodzą od określonej strony.

  • Brak wypierania się: aby uniemożliwić konkretnej stronie odmowę wysłania wiadomości.

Aby osiągnąć te cele, można użyć kombinacji algorytmów i praktyk znanych jako kryptograficzne typy pierwotne w celu utworzenia schematu kryptograficznego. W poniższej tabeli wymieniono kryptograficzne typy pierwotne i ich zastosowania.

Kryptograficzny prymityw Zastosowanie
Szyfrowanie kluczem tajnym (kryptografia symetryczna) Wykonuje transformację danych, aby nie były odczytywane przez inne firmy. Ten typ szyfrowania używa jednego wspólnego klucza tajnego do szyfrowania i odszyfrowywania danych.
Szyfrowanie kluczem publicznym (kryptografia asymetryczna) Wykonuje transformację danych, aby nie były odczytywane przez inne firmy. Ten typ szyfrowania używa pary kluczy publiczny/prywatny do szyfrowania i odszyfrowywania danych.
Podpisywanie kryptograficzne Pomaga sprawdzić, czy dane pochodzą od określonej strony, tworząc podpis cyfrowy unikatowy dla tej strony. W tym procesie są również używane funkcje wyznaczania wartości skrótu.
Skróty kryptograficzne Mapy dane o dowolnej długości do sekwencji bajtów o stałej długości. Skróty są statystycznie unikatowe. Inna sekwencja dwu bajtów nie spowoduje skrótu do tej samej wartości.

Secret-Key szyfrowania

Algorytmy szyfrowania kluczem tajnym używają pojedynczego klucza tajnego do szyfrowania i odszyfrowywania danych. Należy zabezpieczyć klucz przed dostępem nieautoryzowanych agentów, ponieważ każda strona, która go ma, może go użyć do odszyfrowania danych lub zaszyfrowania własnych danych, przechowując je od Ciebie.

Szyfrowanie kluczem tajnym jest również określane jako szyfrowanie symetryczne, ponieważ ten sam klucz jest używany do szyfrowania i odszyfrowywania. Algorytmy szyfrowania kluczem tajnym są bardzo szybkie (w porównaniu z algorytmami kluczy publicznych) i dobrze nadają się do wykonywania przekształceń kryptograficznych na dużych strumieniach danych. Algorytmy szyfrowania asymetrycznego, takie jak RSA, są matematycznie ograniczone pod tym, ile danych mogą szyfrować. Te problemy zazwyczaj nie występują w algorytmach szyfrowania symetrycznego.

Do szyfrowania jednego bloku danych na raz używany jest typ algorytmu klucza tajnego nazywany szyfrem bloków. Szyfry blokowe, takie jak Des (Data Encryption Standard), TripleDES i Advanced Encryption Standard (AES), kryptograficznie przekształcają blok wejściowy o rozmiarze n bajtów w blok wyjściowy zaszyfrowanych bajtów. Jeśli chcesz zaszyfrować lub odszyfrować sekwencję bajtów, musisz zablokować ją blokami. Ponieważ n jest mały (8 bajtów dla DES i TripleDES; 16 bajtów [wartość domyślna], 24 bajty lub 32 bajty dla algorytmu AES), wartości danych, które są większe niż n , muszą być szyfrowane po jednym bloku na raz. Wartości danych, które są mniejsze niż n , należy rozwinąć do n w celu przetworzenia.

Jedna prosta forma szyfru blokowego jest nazywana trybem elektronicznego codebook (QR). Tryb VECTOR nie jest uznawany za bezpieczny, ponieważ nie używa wektora inicjalizacji do zainicjowania pierwszego bloku w postaci zwykłego tekstu. Dla danego klucza tajnego k prosty szyfr blokowy, który nie używa wektora inicjowania, zaszyfruje ten sam blok wejściowy zwykłego tekstu do tego samego bloku wyjściowego szyfru. W związku z tym, jeśli w wejściowym strumieniu w postaci zwykłego tekstu masz zduplikowane bloki, w strumieniu wyjściowym zaszyfrowanego tekstu będą zduplikowane bloki. Te zduplikowane bloki danych wyjściowych ostrzegają nieautoryzowanych użytkowników o słabym szyfrowaniu używanym przez algorytmy, które mogły zostać użyte, oraz o możliwych trybach ataku. W związku z tym tryb szyfrowania THE jest dość narażony na analizę, a ostatecznie kluczowe odnajdywanie.

Klasy szyfrowania bloków, które są dostępne w bibliotece klas bazowych, używają domyślnego trybu łańcucha nazywanego łańcuchem bloków szyfrowania (CBC), chociaż można zmienić to ustawienie domyślne, jeśli chcesz.

Szyfry CBC pokonują problemy związane z szyframi THE, używając wektora inicjalizacji (IV) w celu zaszyfrowania pierwszego bloku zwykłego tekstu. Każdy kolejny blok zwykłego tekstu przechodzi bitowo wyłączoną operację OR (XOR) z poprzednim blokiem szyfrowania przed jego zaszyfrowaniem. W związku z tym każdy blok szyfrowania jest zależny od wszystkich poprzednich bloków. Gdy ten system jest używany, nie można użyć wspólnych nagłówków komunikatów, które mogą być znane nieautoryzowanemu użytkownikowi, aby odwrócić klucz.

Jednym ze sposobów naruszenia bezpieczeństwa danych zaszyfrowanych za pomocą szyfru CBC jest przeprowadzenie wyczerpującego wyszukiwania każdego możliwego klucza. W zależności od rozmiaru klucza używanego do szyfrowania tego rodzaju wyszukiwanie jest bardzo czasochłonne nawet przy użyciu najszybszych komputerów i dlatego jest niewykonalne. Większe rozmiary kluczy są trudniejsze do odszyfrowania. Mimo że szyfrowanie teoretycznie nie uniemożliwia przeciwnikowi pobrania zaszyfrowanych danych, zwiększa to koszt. Jeśli przeprowadzenie wyczerpującego wyszukiwania w celu pobrania istotnych danych tylko z kilku dni trwa trzy miesiące, wyczerpująca metoda wyszukiwania jest niepraktyczna.

Wadą szyfrowania kluczem tajnym jest to, że zakłada się, że dwie strony uzgodniły klucz i iv oraz przekazują swoje wartości. Klucz IV nie jest traktowany jako klucz tajny i można go przesłać za pomocą wiadomości w postaci zwykłego tekstu. Klucz musi być jednak tajny przed nieautoryzowanymi użytkownikami. Z powodu tych problemów szyfrowanie kluczem tajnym jest często używane razem z szyfrowaniem klucza publicznego w celu prywatnego przekazywania wartości klucza i klucza IV.

Zakładając, że Alice i Bob są dwiema stronami, które chcą komunikować się za pośrednictwem niezabezpieczonych kanałów, mogą używać szyfrowania kluczem tajnym w następujący sposób: Alice i Bob zgadzają się na użycie jednego określonego algorytmu (na przykład AES) z określonym kluczem i iv. Alicja tworzy komunikat i tworzy strumień sieciowy (np. nazwany potok lub adres e-mail sieciowy), za pomocą którego ma być wysyłana wiadomość. Następnie szyfruje tekst przy użyciu klucza i iv oraz wysyła zaszyfrowaną wiadomość i IV do Boba przez intranet. Bob odbiera zaszyfrowany tekst i odszyfrowuje go przy użyciu klucza IV i wcześniej uzgodnił klucz. Jeśli transmisja zostanie przechwycona, interceptor nie może odzyskać oryginalnego komunikatu, ponieważ nie zna klucza. W tym scenariuszu tylko klucz musi pozostać tajny. W rzeczywistym scenariuszu Alice lub Bob generuje klucz tajny i używa szyfrowania klucza publicznego (asymetrycznego) w celu przeniesienia klucza tajnego (symetrycznego) do innej strony. Aby uzyskać więcej informacji na temat szyfrowania kluczem publicznym, zobacz następną sekcję.

Program .NET udostępnia następujące klasy, które implementują algorytmy szyfrowania kluczem tajnym:

  • Aes

  • HMACSHA256, HMACSHA384 i HMACSHA512. (Są to technicznie algorytmy klucza tajnego, ponieważ reprezentują kody uwierzytelniania komunikatów, które są obliczane przy użyciu funkcji skrótu kryptograficznego w połączeniu z kluczem tajnym. Zobacz wartości skrótu w dalszej części tego artykułu).

Public-Key szyfrowania

Szyfrowanie kluczem publicznym używa klucza prywatnego, który musi być przechowywany jako tajny przed nieautoryzowanymi użytkownikami, oraz klucza publicznego, który może być publiczny dla każdego. Klucz publiczny i klucz prywatny są połączone matematycznie; Dane zaszyfrowane za pomocą klucza publicznego można odszyfrować tylko za pomocą klucza prywatnego, a dane podpisane przy użyciu klucza prywatnego można zweryfikować tylko przy użyciu klucza publicznego. Klucz publiczny może być dostępny dla każdego; Jest on używany do szyfrowania danych, które mają być wysyłane do strażnika klucza prywatnego. Algorytmy kryptograficzne klucza publicznego są również nazywane algorytmami asymetrycznymi, ponieważ do szyfrowania danych jest wymagany jeden klucz, a inny klucz jest wymagany do odszyfrowania danych. Podstawowa reguła kryptograficzna zabrania ponownego użycia klucza i oba klucze powinny być unikatowe dla każdej sesji komunikacyjnej. Jednak w praktyce klucze asymetryczne są zwykle długotrwałe.

Dwie strony (Alice i Bob) mogą używać szyfrowania kluczem publicznym w następujący sposób: Najpierw Alice generuje parę kluczy publiczny-prywatny. Jeśli Bob chce wysłać Alice zaszyfrowaną wiadomość, prosi ją o jej klucz publiczny. Alice wysyła Robertowi swój klucz publiczny za pośrednictwem niezabezpieczonych sieci, a Bob używa tego klucza do zaszyfrowania wiadomości. Robert wysyła zaszyfrowaną wiadomość do Alicji i odszyfrowuje ją przy użyciu swojego klucza prywatnego. Jeśli Robert otrzymał klucz Alice za pośrednictwem niezabezpiecznego kanału, takiego jak sieć publiczna, bob jest otwarty na atak typu man-in-the-middle. W związku z tym Bob musi sprawdzić u Alice, czy ma poprawną kopię swojego klucza publicznego.

Podczas przekazywania klucza publicznego Alicji nieautoryzowany agent może go przechwycić. Ponadto ten sam agent może przechwycić zaszyfrowany komunikat od Boba. Agent nie może jednak odszyfrować komunikatu przy użyciu klucza publicznego. Komunikat można odszyfrować tylko przy użyciu klucza prywatnego Alicji, który nie został przesłany. Alicja nie używa swojego klucza prywatnego do zaszyfrowania komunikatu odpowiedzi do Boba, ponieważ każda osoba mająca klucz publiczny może odszyfrować wiadomość. Jeśli Alice chce wysłać wiadomość z powrotem do Boba, prosi Go o jego klucz publiczny i szyfruje wiadomość przy użyciu tego klucza publicznego. Bob następnie odszyfrowuje komunikat przy użyciu skojarzonego klucza prywatnego.

W tym scenariuszu Alice i Bob używają szyfrowania kluczem publicznym (asymetrycznym) do transferu klucza tajnego (symetrycznego) i szyfrowania kluczem tajnym przez pozostałą część sesji.

Na poniższej liście przedstawiono porównania algorytmów kryptograficznych klucza publicznego i klucza tajnego:

  • Algorytmy kryptograficzne klucza publicznego używają stałego rozmiaru buforu, natomiast algorytmy kryptograficzne klucza tajnego używają buforu o zmiennej długości.

  • Algorytmy klucza publicznego nie mogą być używane do łańcucha danych w strumienie w sposób, w jaki algorytmy klucza tajnego mogą, ponieważ tylko małe ilości danych mogą być szyfrowane. W związku z tym operacje asymetryczne nie używają tego samego modelu przesyłania strumieniowego co operacje symetryczne.

  • Szyfrowanie kluczem publicznym ma znacznie większą przestrzeń kluczy (zakres możliwych wartości klucza) niż szyfrowanie kluczem tajnym. W związku z tym szyfrowanie kluczem publicznym jest mniej podatne na wyczerpujące ataki, które spowodują wypróbowanie każdego możliwego klucza.

  • Klucze publiczne można łatwo rozpowszechniać, ponieważ nie trzeba ich zabezpieczać, pod warunkiem, że istnieje jakiś sposób weryfikacji tożsamości nadawcy.

  • Niektóre algorytmy klucza publicznego (takie jak RSA i DSA, ale nie Diffie'ego-Hellmana) mogą służyć do tworzenia podpisów cyfrowych w celu zweryfikowania tożsamości nadawcy danych.

  • Algorytmy klucza publicznego są bardzo powolne w porównaniu z algorytmami klucza tajnego i nie są przeznaczone do szyfrowania dużych ilości danych. Algorytmy klucza publicznego są przydatne tylko do przesyłania bardzo małych ilości danych. Zazwyczaj szyfrowanie kluczem publicznym jest używane do szyfrowania klucza i IV, które ma być używane przez algorytm klucza tajnego. Po przeniesieniu klucza i IV szyfrowania klucza tajnego jest używany w pozostałej części sesji.

.NET udostępnia następujące klasy, które implementują algorytmy klucza publicznego:

RSA umożliwia zarówno szyfrowanie, jak i podpisywanie, ale umowy DSA można używać tylko do podpisywania. DsA nie jest tak bezpieczne jak RSA i zalecamy RSA. Diffie-Hellman można używać tylko do generowania kluczy. Ogólnie rzecz biorąc, algorytmy kluczy publicznych są bardziej ograniczone w ich zastosowaniach niż algorytmy kluczy prywatnych.

Podpisy cyfrowe

Algorytmy klucza publicznego mogą być również używane do formowania podpisów cyfrowych. Podpisy cyfrowe uwierzytelniają tożsamość nadawcy (jeśli ufasz jego kluczowi publicznemu) i pomagają chronić integralność danych. Używając klucza publicznego wygenerowanego przez Alice, odbiorca danych Alice może sprawdzić, czy Alice wysłała go, porównując podpis cyfrowy z danymi Alice i kluczem publicznym Alice.

Aby użyć kryptografii klucza publicznego do cyfrowego podpisania komunikatu, Alice najpierw stosuje algorytm wyznaczania wartości skrótu do komunikatu w celu utworzenia skrótu wiadomości. Skrót wiadomości to kompaktowa i unikatowa reprezentacja danych. Następnie Alicja szyfruje podsumowanie wiadomości przy użyciu swojego klucza prywatnego, aby utworzyć swój osobisty podpis. Po otrzymaniu komunikatu i podpisu Bob odszyfrowuje podpis przy użyciu klucza publicznego Alice w celu odzyskania skrótu komunikatu i wyznaczania wartości skrótu komunikatu przy użyciu tego samego algorytmu wyznaczania wartości skrótu, który był używany przez Alice. Jeśli skrót wiadomości, który Bob oblicza dokładnie odpowiada skrótowi wiadomości otrzymanego od Alicji, Bob ma pewność, że komunikat pochodzi od osoby posiadającyj klucz prywatny i że dane nie zostały zmodyfikowane. Jeśli Bob ufa, że Alice jest posiadaczem klucza prywatnego, wie, że komunikat pochodzi od Alice.

Uwaga

Podpis może zostać zweryfikowany przez każdego, ponieważ klucz publiczny nadawcy jest powszechnie używany i zwykle jest uwzględniany w formacie podpisu cyfrowego. Ta metoda nie zachowuje tajemnicy komunikatu; Aby komunikat był tajny, musi być również zaszyfrowany.

.NET udostępnia następujące klasy, które implementują algorytmy podpisów cyfrowych:

Wartości skrótu

Algorytmy wyznaczania wartości skrótu mapuje wartości binarne o dowolnej długości na mniejsze wartości binarne o stałej długości, znane jako wartości skrótu. Wartość skrótu jest liczbową reprezentacją elementu danych. Jeśli zmienisz skrót akapitu w postaci zwykłego tekstu i zmienisz nawet jedną literę akapitu, kolejne skróty będą dawać inną wartość. Jeśli skrót jest silnie kryptograficznie, jego wartość znacznie się zmieni. Jeśli na przykład zmieni się pojedynczy bit komunikatu, funkcja silnego skrótu może tworzyć dane wyjściowe, które różnią się o 50 procent. Wiele wartości wejściowych może mieć wartość skrótu do tej samej wartości wyjściowej. Jednak obliczeniowo nie można znaleźć dwóch odrębnych danych wejściowych, które są skrótami do tej samej wartości.

Dwie strony (Alice i Bob) mogą używać funkcji skrótu w celu zapewnienia integralności komunikatów. Wybierze algorytm wyznaczania wartości skrótu, aby podpisać swoje komunikaty. Alicja napisze komunikat, a następnie utworzy skrót tego komunikatu przy użyciu wybranego algorytmu. Następnie należy wykonać jedną z następujących metod:

  • Alicja wysyła komunikat w postaci zwykłego tekstu i wiadomość z skrótem (podpis cyfrowy) do Boba. Bob odbiera i skrótuje komunikat i porównuje jego wartość skrótu z wartością skrótu otrzymaną od Alicji. Jeśli wartości skrótu są identyczne, komunikat nie został zmieniony. Jeśli wartości nie są identyczne, komunikat został zmieniony po napiseniu go przez Alice.

    Niestety ta metoda nie określa autentyczności nadawcy. Każdy może spersonifikować Alice i wysłać wiadomość do Boba. Mogą podpisać swój komunikat za pomocą tego samego algorytmu wyznaczania wartości skrótu, a Bob może tylko określić, że komunikat jest taki sam jak podpis. Jest to jedna z form ataku typu man-in-the-middle. Aby uzyskać więcej informacji, zobacz przykład Kryptografia nowej generacji bezpiecznej komunikacji (CNG).

  • Alicja wysyła wiadomość w postaci zwykłego tekstu do Boba za pośrednictwem niezabezpieczonych kanałów publicznych. Wysyła ona wiadomość skrótu do Boba za pośrednictwem bezpiecznego kanału prywatnego. Bob odbiera komunikat w postaci zwykłego tekstu, skrótuje go i porównuje skrót z wartością skrótu wymienianą prywatnie. Jeśli skróty są zgodne, Bob zna dwie rzeczy:

    • Komunikat nie został zmieniony.

    • Nadawca komunikatu (Alice) jest autentyczny.

    Aby ten system działał, Alice musi ukryć swoją oryginalną wartość skrótu przed wszystkimi stronami z wyjątkiem Boba.

  • Alice wysyła wiadomość w postaci zwykłego tekstu do Boba za pośrednictwem niezabezpieczonych kanałów publicznych i umieszcza wiadomość w postaci skrótu w swojej publicznie dostępnej witrynie internetowej.

    Ta metoda zapobiega manipulowaniu komunikatami, uniemożliwiając modyfikowanie wartości skrótu przez wszystkich użytkowników. Chociaż komunikat i jego skrót mogą zostać odczytane przez każdego, wartość skrótu może zmienić tylko Alicja. Osoba atakująca, która chce personifikować Alice, będzie wymagać dostępu do witryny internetowej Alice.

Żadna z poprzednich metod nie uniemożliwi odczytywania komunikatów Alicji, ponieważ są one przesyłane w postaci zwykłego tekstu. Pełne zabezpieczenia zwykle wymagają podpisów cyfrowych (podpisywania komunikatów) i szyfrowania.

Program .NET udostępnia następujące klasy implementujące algorytmy wyznaczania wartości skrótu:

.NET udostępnia również funkcje MD5 i SHA1. Jednak algorytmy MD5 i SHA-1 są niezabezpieczone i zamiast tego zaleca się użycie algorytmu SHA-2. Sha-2 obejmuje SHA256, SHA384 i SHA512.

Generowanie liczb losowych

Generowanie liczb losowych jest integralną częścią wielu operacji kryptograficznych. Na przykład klucze kryptograficzne muszą być tak losowe, jak to możliwe, aby nie można było ich odtworzyć. Kryptograficzne generatory liczb losowych muszą generować dane wyjściowe, które są obliczeniowo niewykonalne do przewidywania z prawdopodobieństwem, które jest lepsze niż połowa. W związku z tym każda metoda przewidywania następnego bitu wyjściowego nie może działać lepiej niż losowe zgadywanie. Klasy na .NET używają generatorów liczb losowych do generowania kluczy kryptograficznych.

Klasa RandomNumberGenerator jest implementacją algorytmu generatora liczb losowych.

ClickOnce manifestów

Następujące klasy kryptografii umożliwiają uzyskiwanie i weryfikowanie informacji o podpisach manifestu dla aplikacji wdrożonych przy użyciu ClickOnce technologii:

Ponadto następujące klasy zawierają określone informacje o podpisie:

Kryptografia nowej generacji (CNG)

Klasy Kryptografia nowej generacji (CNG) zapewniają zarządzaną otokę wokół natywnych funkcji CNG. (CNG zastępuje interfejs CryptoAPI). Te klasy mają "Cng" jako część nazw. Centralną klasą otoki CngKey CNG jest klasa kontenera kluczy, która abstrakcję magazynowania i używania kluczy CNG. Ta klasa pozwala bezpiecznie przechowywać parę kluczy lub klucz publiczny i odwoływać się do niego przy użyciu prostej nazwy ciągu. Klasa podpisu oparta na krzywej ECDsaCng wielokropka i klasa ECDiffieHellmanCng szyfrowania mogą używać CngKey obiektów .

Klasa CngKey jest używana do różnych dodatkowych operacji, takich jak otwieranie, tworzenie, usuwanie i eksportowanie kluczy. Zapewnia również dostęp do podstawowego dojścia klucza do użycia podczas bezpośredniego wywoływania funkcji natywnych.

Program .NET zawiera również różne klasy CNG, takie jak następujące:

Zobacz też