Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Tło i teoria
W systemie ochrony danych "klucz" oznacza obiekt, który może zapewnić uwierzytelnione usługi szyfrowania. Każdy klucz jest identyfikowany przez unikatowy identyfikator (identyfikator GUID) i niesie ze sobą informacje algorytmiczne i materiał entropiczny. Zakłada się, że każdy klucz ma unikalną entropię, ale system nie może tego wymusić. Musimy także uwzględnić programistów, którzy mogą ręcznie zmienić pierścień kluczy, modyfikując informacje związane z algorytmem istniejącego klucza. Aby osiągnąć nasze wymagania dotyczące zabezpieczeń, biorąc pod uwagę te przypadki, system ochrony danych ma koncepcję elastyczności kryptograficznej, która umożliwia bezpieczne korzystanie z jednej wartości entropowej w wielu algorytmach kryptograficznych.
Większość systemów, które wspierają zwinność kryptograficzną, robi to poprzez zamieszczenie pewnych informacji identyfikujących o algorytmie wewnątrz ładunku. OID algorytmu jest zazwyczaj dobrym kandydatem do tego. Jednak jednym z problemów, które napotkaliśmy, jest to, że istnieje wiele sposobów określania tego samego algorytmu: "AES" (CNG) i zarządzane Aes, AesManaged, AesCryptoServiceProvider, AesCng i RijndaelManaged (podane określone parametry) klasy są w rzeczywistości takie same, i musimy zachować mapowanie wszystkich tych elementów na poprawny identyfikator OID. Jeśli deweloper chce udostępnić niestandardowy algorytm (a nawet inną implementację AES!), musi powiedzieć nam jego identyfikator OID. Ten dodatkowy krok rejestracji sprawia, że konfiguracja systemu jest szczególnie bolesna.
Cofając się, zdecydowaliśmy, że zbliżamy się do problemu z niewłaściwego kierunku. Identyfikator OID informuje o tym, czym jest algorytm, ale tak naprawdę nie zależy nam na tym. Jeśli musimy bezpiecznie użyć jednej wartości entropowej w dwóch różnych algorytmach, nie trzeba wiedzieć, jakie są algorytmy. Na czym naprawdę nam zależy, to jak się zachowują. Każdy przyzwoity algorytm szyfrowania bloków symetrycznych jest również silną permutacją pseudolosową (PRP): ustal dane wejściowe (klucz, tryb wiązania, IV, tekst jawny), a dane wyjściowe szyfrowania z dużym prawdopodobieństwem będą się różnić od innych algorytmów szyfrowania bloków symetrycznych, biorąc pod uwagę te same dane wejściowe. Podobnie każda przyzwoita funkcja skrótu z kluczem jest również silną funkcją pseudolosową (PRF), a biorąc pod uwagę stały zestaw danych wejściowych, najczęściej jej wyjścia będą różniły się od wyjść każdej innej funkcji skrótu z kluczem.
Używamy pojęcia silnych PRP i PRF do tworzenia nagłówka kontekstu. Ten nagłówek kontekstu zasadniczo działa jako stabilny odcisk palca nad algorytmami używanymi dla danej operacji i zapewnia elastyczność kryptograficzną wymaganą przez system ochrony danych. Ten nagłówek jest powtarzalny i jest używany później w ramach procesu wyprowadzania podklucza. Istnieją dwa różne sposoby tworzenia nagłówka kontekstu w zależności od trybów działania algorytmów bazowych.
Szyfrowanie w trybie CBC i uwierzytelnianie HMAC
Nagłówek kontekstu składa się z następujących składników:
[16 bitów] Wartość 00 00, czyli znacznik oznaczający "szyfrowanie CBC + uwierzytelnianie HMAC".
[32 bity] Długość klucza (w bajtach big-endian) algorytmu szyfrowania bloków symetrycznych.
[32 bity] Rozmiar bloku (w bajtach, big-endian) zastosowanego w algorytmie symetrycznego szyfrowania blokowego.
[32 bity] Długość klucza (w bajtach big-endian) algorytmu HMAC. (Obecnie rozmiar klucza zawsze odpowiada rozmiarowi skrótu).
[32 bity] Rozmiar skrótu (w bajtach big-endian) algorytmu HMAC.
EncCBC(K_E, IV, ""), który jest wyjściem algorytmu szyfrowania bloków symetrycznych przy pustym łańcuchu wejściowym i gdzie IV jest wektorem zerowym. KonstrukcjaK_Ezostała opisana poniżej.MAC(K_H, ""), który jest wynikiem działania algorytmu HMAC dla pustych danych wejściowych. BudowaK_Hjest opisana poniżej.
W idealnym przypadku możemy przekazać wektory zerowe dla K_E i K_H. Chcemy jednak uniknąć sytuacji, w której podstawowy algorytm sprawdza istnienie słabych kluczy przed wykonaniem jakichkolwiek operacji (w szczególności DES i 3DES), co uniemożliwia użycie prostego lub powtarzalnego wzorca, takiego jak wektor all-zero.
Zamiast tego używamy NIST SP800-108 KDF w trybie licznika (zobacz NIST SP800-108, Sec. 5.1) z kluczem o zerowej długości, etykietą i kontekstem oraz HMACSHA512 jako podstawową funkcją PRF. Uzyskujemy | K_E | + | K_H | bajtów wyjściowych, a następnie rozkładamy wynik na K_E i K_H. Matematycznie jest to reprezentowane w następujący sposób.
( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")
Przykład: AES-192-CBC + HMACSHA256
Rozważmy na przykład przypadek, w którym algorytm szyfrowania bloków symetrycznych to AES-192-CBC, a algorytm sprawdzania poprawności jest HMACSHA256. System wygeneruje nagłówek kontekstu, wykonując następujące kroki.
Przyjmijmy najpierw ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), gdzie | K_E | = 192 bits oraz | K_H | = 256 bits zgodnie z określonymi algorytmami. Prowadzi to do K_E = 5BB6..21DD i K_H = A04A..00A9 w poniższym przykładzie:
5B B6 C9 83 13 78 22 1D 8E 10 73 CA CF 65 8E B0
61 62 42 71 CB 83 21 DD A0 4A 05 00 5B AB C0 A2
49 6F A5 61 E3 E2 49 87 AA 63 55 CD 74 0A DA C4
B7 92 3D BF 59 90 00 A9
Następnie oblicz Enc_CBC (K_E, IV, "") dla AES-192-CBC, biorąc pod uwagę IV = 0* i K_E jak powyżej.
result := F474B1872B3B53E4721DE19C0841DB6F
Następnie oblicz MAC(K_H, "") dla HMACSHA256, wykorzystując K_H jako powyżej.
result := D4791184B996092EE1202F36E8608FA8FBD98ABDFF5402F264B1D7211536220C
Spowoduje to utworzenie poniższego pełnego nagłówka kontekstu:
00 00 00 00 00 18 00 00 00 10 00 00 00 20 00 00
00 20 F4 74 B1 87 2B 3B 53 E4 72 1D E1 9C 08 41
DB 6F D4 79 11 84 B9 96 09 2E E1 20 2F 36 E8 60
8F A8 FB D9 8A BD FF 54 02 F2 64 B1 D7 21 15 36
22 0C
Ten nagłówek kontekstu to odcisk palca pary uwierzytelnionego algorytmu szyfrowania (szyfrowanie AES-192-CBC + weryfikacja HMACSHA256). Składniki, jak opisano powyżej , to:
znacznik
(00 00)długość klucza szyfrującego blokowego
(00 00 00 18)rozmiar bloku szyfrowania
(00 00 00 10)długość klucza HMAC
(00 00 00 20)rozmiar skrótu HMAC
(00 00 00 20)dane wyjściowe PRP szyfru blokowego
(F4 74 - DB 6F)idane wyjściowe HMAC PRF
(D4 79 - end).
Uwaga / Notatka
Szyfrowanie w trybie CBC i nagłówek kontekstu uwierzytelniania HMAC jest zbudowany w taki sam sposób, niezależnie od tego, czy implementacje algorytmów są dostarczane przez CNG systemu Windows, czy przez zarządzane typy SymmetricAlgorithm i KeyedHashAlgorithm. Dzięki temu aplikacje działające w różnych systemach operacyjnych mogą niezawodnie tworzyć ten sam nagłówek kontekstu, mimo że implementacje algorytmów różnią się między systemami operacyjnymi. (W praktyce KeyedHashAlgorithm nie musi być właściwym HMAC. Może być użyty dowolny typ algorytmu skrótu z kluczem.)
Przykład: 3DES-192-CBC + HMACSHA1
Najpierw zdefiniuj ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), gdzie zgodnie z określonymi algorytmami | K_E | = 192 bits i | K_H | = 160 bits. Prowadzi to do K_E = A219..E2BB i K_H = DC4A..B464 w poniższym przykładzie:
A2 19 60 2F 83 A9 13 EA B0 61 3A 39 B8 A6 7E 22
61 D9 F8 6C 10 51 E2 BB DC 4A 00 D7 03 A2 48 3E
D1 F7 5A 34 EB 28 3E D7 D4 67 B4 64
Następnie oblicz Enc_CBC (K_E, IV, "") dla 3DES-192-CBC mając IV = 0* i K_E jak powyżej.
result := ABB100F81E53E10E
Następnie oblicz wartość MAC(K_H, "") dla HMACSHA1 według powyższych wskazań.
result := 76EB189B35CF03461DDF877CD9F4B1B4D63A7555
Spowoduje to utworzenie pełnego nagłówka kontekstu, będącego odciskiem palca pary algorytmów szyfrowania uwierzytelnionego (szyfrowanie 3DES-192-CBC + walidacja HMACSHA1), jak pokazano poniżej.
00 00 00 00 00 18 00 00 00 08 00 00 00 14 00 00
00 14 AB B1 00 F8 1E 53 E1 0E 76 EB 18 9B 35 CF
03 46 1D DF 87 7C D9 F4 B1 B4 D6 3A 75 55
Składniki są rozdzielane w następujący sposób:
znacznik
(00 00)długość klucza bloku szyfrującego
(00 00 00 18)rozmiar bloku szyfrowania
(00 00 00 08)długość klucza HMAC
(00 00 00 14)rozmiar skrótu HMAC
(00 00 00 14)wyjście
(AB B1 - E1 0E)funkcji PRP szyfru blokowego idane wyjściowe HMAC PRF
(76 EB - end).
Szyfrowanie w trybie Galois/licznika i uwierzytelnianie
Nagłówek kontekstu składa się z następujących składników:
[16 bitów] Wartość 00 01, czyli znacznik oznaczający "szyfrowanie I uwierzytelnianie GCM".
[32 bity] Długość klucza (w bajtach big-endian) algorytmu szyfrowania bloków symetrycznych.
[32 bity] Rozmiar licznika (w bajtach, w formacie big-endian) używanego podczas operacji szyfrowania uwierzytelnionego. (W naszym systemie jest to ustalone na 96 bitów).
[32 bity] Rozmiar bloku (w bajtach, big-endian) symetrycznego algorytmu szyfrowania blokowego. (W przypadku usługi GCM jest to stałe w rozmiarze bloku = 128 bitów).
[32 bity] Rozmiar tagu uwierzytelniania (w bajtach big-endian) generowany przez uwierzytelnioną funkcję szyfrowania. (W naszym systemie jest to stałe przy rozmiarze tagu = 128 bitów).
[128 bitów] Tag
Enc_GCM (K_E, nonce, ""), który jest wynikiem symetrycznego algorytmu szyfrowania bloków dla pustego ciągu wejściowego i gdzie nonce jest 96-bitowym wektorem całkowicie zerowym.
K_E jest uzyskiwany przy użyciu tego samego mechanizmu co w scenariuszu szyfrowania CBC i uwierzytelniania HMAC. Jednak ponieważ K_H nie jest używane tutaj, zasadniczo mamy | K_H | = 0 wartość, a algorytm sprowadza się do poniższej postaci.
K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")
Przykład: AES-256-GCM
Najpierw niech K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), gdzie | K_E | = 256 bits.
K_E := 22BC6F1B171C08C4AE2F27444AF8FC8B3087A90006CAEA91FDCFB47C1B8733B8
Następnie należy obliczyć znacznik uwierzytelniania Enc_GCM (K_E, nonce, "") dla AES-256-GCM, biorąc pod uwagę nonce = 096 i K_E jak powyżej.
result := E7DCCE66DF855A323A6BB7BD7A59BE45
Spowoduje to utworzenie poniższego pełnego nagłówka kontekstu:
00 01 00 00 00 20 00 00 00 0C 00 00 00 10 00 00
00 10 E7 DC CE 66 DF 85 5A 32 3A 6B B7 BD 7A 59
BE 45
Składniki są rozdzielane w następujący sposób:
znacznik
(00 01)długość klucza szyfru blokowego
(00 00 00 20)rozmiar nonce
(00 00 00 0C)rozmiar bloku szyfrowania
(00 00 00 10)rozmiar
(00 00 00 10)tagu uwierzytelniania ikarta uwierzytelniania z uruchomienia szyfru blokowego
(E7 DC - end).
ASP.NET Core