Sdílet prostřednictvím


Kontextová záhlaví v ASP.NET Core

Pozadí a teorie

V systému ochrany dat "klíč" znamená objekt, který může poskytovat ověřené šifrovací služby. Každý klíč je identifikován jedinečným ID (GUID) a nese s ním algoritmické informace a entropický materiál. Je zamýšleno, že každý klíč má jedinečnou entropii, ale systém to nemůže vynutit, a musíme také počítat s vývojáři, kteří můžou změnit okruh klíčů ručně úpravou algoritmických informací existujícího klíče v okruhu klíčů. Abychom dosáhli bezpečnostních požadavků v těchto případech, systém ochrany dat má koncept kryptografické flexibility, která umožňuje bezpečně používat jednu entropickou hodnotu napříč několika kryptografickými algoritmy.

Většina systémů, které podporují kryptografickou flexibilitu, tak, že do datové části zahrne některé identifikační informace o algoritmu. Identifikátor OID algoritmu je obecně vhodným kandidátem na tento algoritmus. Jedním z problémů, na který jsme narazili, je, že existují různé způsoby, jak určit stejný algoritmus: "AES" (CNG) a spravované třídy Aes, AesManaged, AesCryptoServiceProvider, AesCng a RijndaelManaged (vzhledem ke konkrétním parametrům) jsou ve skutečnosti stejné a musíme zachovat mapování všech těchto tříd na správný identifikátor OID. Pokud by vývojář chtěl poskytnout vlastní algoritmus (nebo dokonce jinou implementaci AES!), museli by nám sdělit jeho identifikátor OID. Díky tomuto dodatečnému kroku registrace je konfigurace systému obzvláště bolestivá.

Pozadu jsme se rozhodli, že se k problému blížíme z nesprávného směru. Identifikátor OID vám řekne, co je algoritmus, ale na tom ve skutečnosti nezajímáme. Pokud potřebujeme bezpečně použít jednu entropickou hodnotu ve dvou různých algoritmech, není nutné vědět, co jsou algoritmy skutečně. Záleží nám na tom, jak se chovají. Jakýkoli slušný symetrický blokový šifrovací algoritmus je také silná pseudorandomní permutace (PRP): opravte vstupy (key, chaining mode, IV, plaintext) a výstup šifry šifry šifry bude s nepřehlednou pravděpodobností odlišný od jakéhokoli jiného symetrického blokového šifrovacího algoritmu s použitím stejných vstupů. Podobně každá slušná funkce hash s klíči je také silná pseudorandomní funkce (PRF) a vzhledem k pevné vstupní sadě bude její výstup výrazně odlišné od jakékoli jiné klíčové hash funkce.

Tento koncept silných prsp a PRF používáme k vytvoření hlavičky kontextu. Tato hlavička kontextu v podstatě funguje jako stabilní kryptografický otisk nad algoritmy, které se používají pro jakoukoli danou operaci, a poskytuje kryptografickou flexibilitu potřebnou systémem ochrany dat. Tato hlavička je reprodukovatelná a později se použije jako součást procesu odvození podklíče. Existují dva různé způsoby, jak vytvořit hlavičku kontextu v závislosti na režimech provozu podkladových algoritmů.

Šifrování v režimu CBC + ověřování HMAC

Záhlaví kontextu se skládá z následujících komponent:

  • [16 bitů] Hodnota 00 00, což je značka označující "šifrování CBC + ověřování HMAC".

  • [32 bitů] Délka klíče (v bajtech, big-endian) symetrického blokového šifrovacího algoritmu.

  • [32 bitů] Velikost bloku (v bajtech, big-endian) šifrovacího algoritmu symetrického bloku.

  • [32 bitů] Délka klíče (v bajtech, big-endian) algoritmu HMAC. (V současné době se velikost klíče vždy shoduje s velikostí hodnoty digest.)

  • [32 bitů] Velikost hodnot hash (v bajtech, big-endian) algoritmu HMAC.

  • EncCBC(K_E, IV, ""), což je výstup symetrického blokového šifrovacího algoritmu při zadání prázdného řetězce a kde IV je all-nula vektor. Konstrukce K_E je popsána níže.

  • MAC(K_H, ""), což je výstup algoritmu HMAC zadaný prázdným řetězcovým vstupem. Konstrukce K_H je popsána níže.

V ideálním případě bychom mohli předat všechny nuly vektory pro K_E a K_H. Chceme se však vyhnout situaci, kdy základní algoritmus před provedením jakýchkoli operací (zejména DES a 3DES) kontroluje existenci slabých klíčů, což brání použití jednoduchého nebo opakovatelného vzoru jako all-zero vektor.

Místo toho použijeme NIST SP800-108 KDF v režimu čítače (viz NIST SP800-108, s. 5.1) s klíčem nulové délky, popiskem a kontextem a HMACSHA512 jako podkladovou PRF. Odvozujeme | K_E | + | K_H | bajty výstupu a pak výsledek K_E rozložíme do sebe a K_H samy o sobě. Matematicky je to reprezentováno následujícím způsobem.

( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")

Příklad: AES-192-CBC + HMACSHA256

Představte si například případ, kdy algoritmus symetrického blokového šifrování je AES-192-CBC a ověřovací algoritmus je HMACSHA256. Systém vygeneruje hlavičku kontextu pomocí následujícího postupu.

Nejprve nechte ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), kde | K_E | = 192 bits a | K_H | = 256 bits podle zadaných algoritmů. To vede k K_E = 5BB6..21DD následujícímu příkladu:K_H = A04A..00A9

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

Dále se počítají pro Enc_CBC (K_E, IV, "") AES-192-CBC a IV = 0* K_E jak je uvedeno výše.

result := F474B1872B3B53E4721DE19C0841DB6F

V dalším kroku se počítají MAC(K_H, "") pro HMACSHA256 uvedené K_H výše.

result := D4791184B996092EE1202F36E8608FA8FBD98ABDFF5402F264B1D7211536220C

Výsledkem je následující úplná hlavička kontextu:

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

Toto záhlaví kontextu je kryptografický otisk dvojice ověřených šifrovacích algoritmů (šifrování AES-192-CBC + ověření HMACSHA256). Komponenty, jak je popsáno výše , jsou:

  • značka (00 00)

  • délka šifrovacího klíče bloku (00 00 00 18)

  • velikost bloku bloku šifry (00 00 00 10)

  • délka klíče HMAC (00 00 00 20)

  • velikost hodnoty hash HMAC (00 00 00 20)

  • blokový výstup (F4 74 - DB 6F) PRP a

  • výstup (D4 79 - end)HMAC PRF .

Poznámka

Šifrování V režimu CBC + hlavička kontextu ověřování HMAC je sestavena stejným způsobem bez ohledu na to, zda jsou implementace algoritmů poskytovány systémem Windows CNG nebo spravovanými typy SymmetricAlgorithm a KeyedHashAlgorithm. To umožňuje aplikacím běžícím v různých operačních systémech spolehlivě vytvořit stejnou hlavičku kontextu, i když se implementace algoritmů mezi operačními systémy liší. (V praxi nemusí keyedHashAlgorithm být správný HMAC. Může se jednat o libovolný typ algoritmu hash s klíči.)

Příklad: 3DES-192-CBC + HMACSHA1

Nejprve nechte ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), kde | K_E | = 192 bits a | K_H | = 160 bits podle zadaných algoritmů. To vede k K_E = A219..E2BB následujícímu příkladu:K_H = DC4A..B464

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

V dalším kroku se počítají pro Enc_CBC (K_E, IV, "") 3DES-192-CBC a K_E IV = 0* jak je uvedeno výše.

result := ABB100F81E53E10E

V dalším kroku se vypočítá HMACSHA1 MAC(K_H, "") podle K_H výše uvedeného.

result := 76EB189B35CF03461DDF877CD9F4B1B4D63A7555

Tím se vytvoří úplná hlavička kontextu, což je kryptografický otisk dvojice ověřených šifrovacích algoritmů (šifrování 3DES-192-CBC + ověření HMACSHA1), jak je znázorněno níže:

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

Komponenty se rozdělí takto:

  • značka (00 00)

  • délka šifrovacího klíče bloku (00 00 00 18)

  • velikost bloku bloku šifry (00 00 00 08)

  • délka klíče HMAC (00 00 00 14)

  • velikost hodnoty hash HMAC (00 00 00 14)

  • blokový výstup (AB B1 - E1 0E) PRP a

  • výstup (76 EB - end)HMAC PRF .

Šifrování galois/režim čítače + ověřování

Záhlaví kontextu se skládá z následujících komponent:

  • [16 bitů] Hodnota 00 01, což je značka označující "šifrování GCM + ověřování".

  • [32 bitů] Délka klíče (v bajtech, big-endian) symetrického blokového šifrovacího algoritmu.

  • [32 bitů] Velikost nonce (v bajtech, big-endian) použitá během ověřených operací šifrování. (V našem systému je to pevně nastaveno na nece velikost = 96 bitů.)

  • [32 bitů] Velikost bloku (v bajtech, big-endian) šifrovacího algoritmu symetrického bloku. (U GCM je to pevné při velikosti bloku = 128 bitů.)

  • [32 bitů] Velikost ověřovací značky (v bajtech, big-endian) vytvořená ověřenou šifrovací funkcí. (V našem systému je to pevně nastaveno na velikost značky = 128 bitů.)

  • [128 bitů] Značka Enc_GCM (K_E, nonce, ""), která je výstupem symetrického blokového šifrovacího algoritmu při zadání prázdného řetězce a kde nonce je 96bitový all-nula vektor.

K_E je odvozen pomocí stejného mechanismu jako ve scénáři ověřování CBC + HMAC. Vzhledem k tomu, že zde není K_H žádná hra, v podstatě máme | K_H | = 0a algoritmus se sbalí do níže uvedené formy.

K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = "")

Příklad: AES-256-GCM

Za prvé, let K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), kde | K_E | = 256 bits.

K_E := 22BC6F1B171C08C4AE2F27444AF8FC8B3087A90006CAEA91FDCFB47C1B8733B8

Dále vypočítá značku Enc_GCM (K_E, nonce, "") ověřování pro AES-256-GCM danou nonce = 096 a K_E výše uvedenou.

result := E7DCCE66DF855A323A6BB7BD7A59BE45

Výsledkem je následující úplná hlavička kontextu:

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

Komponenty se rozdělí takto:

  • značka (00 01)

  • délka šifrovacího klíče bloku (00 00 00 20)

  • velikost beze změn (00 00 00 0C)

  • velikost bloku bloku šifry (00 00 00 10)

  • velikost (00 00 00 10) značky ověřování a

  • ověřovací značka ze spuštění blokové šifry (E7 DC - end).