Udostępnij za pośrednictwem


Wyprowadzanie podklucza i uwierzytelnione szyfrowanie w usłudze ASP.NET Core

Większość kluczy w pierścieniu kluczy będzie zawierać jakąś formę entropii i będzie zawierać informacje algorytmiczne z informacją "Szyfrowanie w trybie CBC + walidacja HMAC" lub "Szyfrowanie I walidacja GCM". W takich przypadkach odwołujemy się do osadzonej entropii jako głównego materiału kluczowego (lub KM) dla tego klucza i wykonujemy funkcję wyprowadzania kluczy, aby uzyskać klucze, które będą używane do rzeczywistych operacji kryptograficznych.

Uwaga

Klucze są abstrakcyjne, a implementacja niestandardowa może nie zachowywać się tak jak poniżej. Jeśli klucz zapewnia własną implementację IAuthenticatedEncryptor zamiast używać jednej z naszych wbudowanych fabryk, mechanizm opisany w tej sekcji nie ma już zastosowania.

Dodatkowe uwierzytelnione dane i wyprowadzenie podklucza

Interfejs IAuthenticatedEncryptor służy jako podstawowy interfejs dla wszystkich uwierzytelnionych operacji szyfrowania. Metoda Encrypt przyjmuje dwa bufory: zwykły tekst i dodatkoweAuthenticatedData (AAD). Przepływ zawartości zwykłego tekstu bez zmian wywołania metody IDataProtector.Protect, ale usługa AAD jest generowana przez system i składa się z trzech składników:

  1. 32-bitowy nagłówek magic 09 F0 F9 F0, który identyfikuje tę wersję systemu ochrony danych.

  2. Identyfikator klucza 128-bitowego.

  3. Ciąg o zmiennej długości utworzony na podstawie łańcucha przeznaczenia, który utworzył IDataProtector operację wykonującą tę operację.

Ponieważ usługa AAD jest unikatowa dla krotki wszystkich trzech składników, możemy jej użyć do uzyskiwania nowych kluczy z usługi KM zamiast używania samej usługi KM we wszystkich naszych operacjach kryptograficznych. Dla każdego wywołania metody IAuthenticatedEncryptor.Encryptnastępuje następujący proces wyprowadzania klucza:

( K_E, K_H ) = SP800_108_CTR_HMACSHA512(K_M, AAD, contextHeader || keyModifier)

W tym miejscu wywołujemy NIST SP800-108 KDF w trybie licznika (zobacz NIST SP800-108, s. 5.1) z następującymi parametrami:

  • Klucz wyprowadzania klucza (KDK) = K_M

  • PRF = HMACSHA512

  • label = additionalAuthenticatedData

  • context = contextHeader || keyModifier

Nagłówek kontekstu ma zmienną długość i zasadniczo służy jako odcisk palca algorytmów, dla których wyprowadzamy K_E i K_H. Modyfikator klucza jest ciągiem 128-bitowym generowanym losowo dla każdego wywołania Encrypt i służy w celu zapewnienia z przytłaczającym prawdopodobieństwem, że KE i KH są unikatowe dla tej konkretnej operacji szyfrowania uwierzytelniania, nawet jeśli wszystkie inne dane wejściowe do KDF są stałe.

W przypadku operacji | K_E | szyfrowania w trybie CBC i weryfikacji HMAC jest długość symetrycznego klucza szyfrowania bloku i | K_H | jest rozmiarem skrótu procedury HMAC. W przypadku operacji szyfrowania i walidacji usługi GCM. | K_H | = 0

Szyfrowanie w trybie CBC i walidacja HMAC

Po K_E wygenerowaniu za pomocą powyższego mechanizmu generujemy losowy wektor inicjowania i uruchamiamy algorytm szyfrowania bloków symetrycznych, aby zaszyfrować zwykły tekst. Wektor inicjowania i tekst szyfrowania są następnie uruchamiane przez procedurę HMAC zainicjowaną przy użyciu klucza K_H w celu utworzenia adresu MAC. Ten proces i zwracana wartość są reprezentowane graficznie poniżej.

CBC-mode process and return

output:= keyModifier || iv || E_cbc (K_E,iv,data) || HMAC(K_H, iv || E_cbc (K_E,iv,data))

Uwaga

Implementacja IDataProtector.Protect będzie poprzedzać nagłówek magic i identyfikator klucza do danych wyjściowych przed zwróceniem go do obiektu wywołującego. Ponieważ nagłówek magic i identyfikator klucza są niejawnie częścią usługi AAD, a modyfikator klucza jest podawany jako dane wejściowe do usługi KDF, oznacza to, że każdy bajt końcowego zwróconego ładunku jest uwierzytelniany przez komputer MAC.

Szyfrowanie w trybie Galois/Counter + walidacja

Po K_E wygenerowaniu za pomocą powyższego mechanizmu generujemy losową wartość 96-bitową i uruchamiamy algorytm szyfrowania bloków symetrycznych, aby zaszyfrować zwykły tekst i utworzyć tag uwierzytelniania 128-bitowego.

GCM-mode process and return

output := keyModifier || nonce || E_gcm (K_E,nonce,data) || authTag

Uwaga

Mimo że usługa GCM natywnie obsługuje koncepcję usługi AAD, nadal przekazujemy usługę AAD tylko do oryginalnej usługi KDF, decydując się przekazać pusty ciąg do usługi GCM dla parametru usługi AAD. Przyczyną tego jest dwa razy. Po pierwsze, aby zapewnić elastyczność, nigdy nie chcemy używać K_M bezpośrednio jako klucza szyfrowania. Ponadto usługa GCM nakłada na swoje dane wejściowe bardzo ścisłe wymagania dotyczące unikatowości. Prawdopodobieństwo, że rutyna szyfrowania GCM jest kiedykolwiek wywoływana na co najmniej dwóch odrębnych zestawach danych wejściowych z tą samą parą (klucz, nonce) nie może przekraczać 2^-32. Jeśli naprawimy K_E , nie możemy wykonać więcej niż 2^32 operacji szyfrowania przed uruchomieniem afoul limitu 2^-32. Może to wydawać się bardzo dużą liczbą operacji, ale serwer internetowy o dużym natężeniu ruchu może przechodzić przez 4 miliardy żądań w ciągu zaledwie kilku dni, dobrze w normalnym okresie istnienia dla tych kluczy. Aby zachować zgodność z 2^-32 limitem prawdopodobieństwa, nadal używamy modyfikatora 128-bitowego i 96-bitowego nonce, który radykalnie rozszerza liczbę operacji do wykorzystania dla danego K_Melementu . Dla uproszczenia projektu udostępniamy ścieżkę kodu KDF między operacjami CBC i GCM, a ponieważ usługa AAD jest już uwzględniana w usłudze KDF, nie ma potrzeby przekazywania jej do procedury GCM.