Condividi tramite


Intestazioni di contesto in ASP.NET Core

Background e teoria

Nel sistema di protezione dei dati, una "chiave" indica un oggetto in grado di fornire servizi di crittografia autenticati. Ogni chiave viene identificata da un ID univoco (un GUID) e contiene informazioni algoritmiche e materiale entropico. È previsto che ogni chiave contenga entropia univoca, ma il sistema non può applicarlo ed è anche necessario tenere conto per gli sviluppatori che potrebbero modificare manualmente l'anello di chiave modificando le informazioni algoritmiche di una chiave esistente nell'anello delle chiavi. Per ottenere i requisiti di sicurezza in questi casi, il sistema di protezione dei dati ha un concetto di agilità crittografica, che consente di usare in modo sicuro un singolo valore entropico tra più algoritmi crittografici.

La maggior parte dei sistemi che supportano l'agilità crittografica lo fanno includendo alcune informazioni di identificazione sull'algoritmo all'interno del payload. L'OID dell'algoritmo è in genere un buon candidato per questo. Tuttavia, un problema riscontrato è che esistono diversi modi per specificare lo stesso algoritmo: "AES" (CNG) e le classi Aes gestite, AesManaged, AesCryptoServiceProvider, AesCng e RijndaelManaged (dati parametri specifici) sono tutte la stessa cosa e sarebbe necessario mantenere un mapping di tutti questi elementi all'OID corretto. Se uno sviluppatore vuole fornire un algoritmo personalizzato (o anche un'altra implementazione di AES!), deve indicare l'OID. Questo passaggio di registrazione aggiuntivo rende particolarmente dolorosa la configurazione del sistema.

Tornando indietro, abbiamo deciso che stavamo avvicinando il problema dalla direzione sbagliata. Un OID indica che cos'è l'algoritmo, ma in realtà non ci interessa. Se è necessario usare un singolo valore entropico in modo sicuro in due algoritmi diversi, non è necessario sapere quali sono effettivamente gli algoritmi. Quello che ci interessa è come si comportano. Qualsiasi algoritmo di crittografia a blocchi simmetrici decenti è anche una forte permutazione pseudorandoma (PRP): correggere gli input (chiave, modalità di concatenamento, IV, testo non crittografato) e l'output del testo crittografato sarà distinto da qualsiasi altro algoritmo di crittografia a blocchi simmetrici dato gli stessi input. Analogamente, qualsiasi funzione hash con chiave decente è anche una funzione pseudorandom complessa (PRF) e dato che un set di input fisso il relativo output sarà estremamente distinto da qualsiasi altra funzione hash con chiave.

Per creare un'intestazione di contesto, viene usato questo concetto di prp e prfs sicuri. Questa intestazione di contesto funge essenzialmente da identificazione personale stabile sugli algoritmi in uso per qualsiasi operazione specifica e offre l'agilità crittografica necessaria per il sistema di protezione dei dati. Questa intestazione è riproducibile e viene usata in un secondo momento come parte del processo di derivazione della sottochiave. Esistono due modi diversi per compilare l'intestazione del contesto a seconda delle modalità di funzionamento degli algoritmi sottostanti.

Crittografia in modalità CBC + autenticazione HMAC

L'intestazione del contesto è costituita dai componenti seguenti:

  • [16 bit] Valore 00 00, ovvero un marcatore che indica "Crittografia CBC + autenticazione HMAC".

  • [32 bit] Lunghezza della chiave (in byte, big-endian) dell'algoritmo di crittografia a blocchi simmetrici.

  • [32 bit] Dimensione del blocco (in byte, big-endian) dell'algoritmo di crittografia a blocchi simmetrici.

  • [32 bit] Lunghezza della chiave (in byte, big-endian) dell'algoritmo HMAC. Attualmente le dimensioni della chiave corrispondono sempre alla dimensione del digest.

  • [32 bit] Dimensioni del digest (in byte, big-endian) dell'algoritmo HMAC.

  • EncCBC(K_E, IV, ""), che è l'output dell'algoritmo di crittografia a blocchi simmetrici dato un input stringa vuoto e dove IV è un vettore all-zero. La costruzione di è descritta di K_E seguito.

  • MAC(K_H, ""), che è l'output dell'algoritmo HMAC dato un input stringa vuoto. La costruzione di è descritta di K_H seguito.

Idealmente, è possibile passare vettori all-zero per K_E e K_H. Tuttavia, si vuole evitare la situazione in cui l'algoritmo sottostante verifica l'esistenza di chiavi deboli prima di eseguire qualsiasi operazione (in particolare DES e 3DES), che impedisce l'uso di un modello semplice o ripetibile come un vettore all-zero.

Usiamo invece NIST SP800-108 KDF in modalità contatore (vedere NIST SP800-108, Sec. 5.1) con una chiave, un'etichetta e un contesto di lunghezza zero e HMACSHA512 come prf sottostante. Si derivano | K_E | + | K_H | byte di output, quindi si scompone il risultato in K_E e K_H in se stessi. Matematicamente, questo è rappresentato come segue.

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

Esempio: AES-192-CBC + HMACSHA256

Si consideri ad esempio il caso in cui l'algoritmo di crittografia a blocchi simmetrici sia AES-192-CBC e l'algoritmo di convalida sia HMACSHA256. Il sistema genererà l'intestazione di contesto seguendo questa procedura.

Prima di tutto, lasciare ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), dove | K_E | = 192 bits e | K_H | = 256 bits in base agli algoritmi specificati. Questo porta a K_E = 5BB6..21DD e K_H = A04A..00A9 nell'esempio seguente:

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

Successivamente, calcolare Enc_CBC (K_E, IV, "") per AES-192-CBC specificato IV = 0* e K_E come indicato in precedenza.

result := F474B1872B3B53E4721DE19C0841DB6F

Successivamente, calcolare MAC(K_H, "") per HMACSHA256 specificato K_H come indicato in precedenza.

result := D4791184B996092EE1202F36E8608FA8FBD98ABDFF5402F264B1D7211536220C

In questo modo viene eseguita l'intestazione di contesto completa seguente:

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

Questa intestazione di contesto è l'identificazione personale della coppia di algoritmi di crittografia autenticata (crittografia AES-192-CBC + convalida HMACSHA256). I componenti, come descritto in precedenza , sono:

  • marcatore (00 00)

  • lunghezza della chiave di crittografia a blocchi (00 00 00 18)

  • la dimensione del blocco di crittografia (00 00 00 10)

  • lunghezza del tasto HMAC (00 00 00 20)

  • dimensioni del digest HMAC (00 00 00 20)

  • l'output (F4 74 - DB 6F) PRP della crittografia a blocchi e

  • output (D4 79 - end)prf HMAC.

Nota

L'intestazione del contesto di autenticazione CBC + HMAC viene creata nello stesso modo indipendentemente dal fatto che le implementazioni degli algoritmi vengano fornite da Windows CNG o dai tipi SymmetricAlgorithm e KeyedHashAlgorithm gestiti. Ciò consente alle applicazioni in esecuzione in sistemi operativi diversi di produrre in modo affidabile la stessa intestazione di contesto anche se le implementazioni degli algoritmi differiscono tra i sistemi operativi. In pratica, keyedHashAlgorithm non deve essere un HMAC appropriato. Può essere qualsiasi tipo di algoritmo hash con chiave.

Esempio: 3DES-192-CBC + HMACSHA1

Prima di tutto, lasciare ( K_E || K_H ) = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), dove | K_E | = 192 bits e | K_H | = 160 bits in base agli algoritmi specificati. Questo porta a K_E = A219..E2BB e K_H = DC4A..B464 nell'esempio seguente:

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

Successivamente, calcolare Enc_CBC (K_E, IV, "") per 3DES-192-CBC specificato IV = 0* e K_E come indicato in precedenza.

result := ABB100F81E53E10E

Successivamente, calcolare MAC(K_H, "") per HMACSHA1 specificato K_H come indicato in precedenza.

result := 76EB189B35CF03461DDF877CD9F4B1B4D63A7555

In questo modo viene generata l'intestazione di contesto completa, ovvero un'identificazione personale della coppia di algoritmi di crittografia autenticata (crittografia 3DES-192-CBC + convalida HMACSHA1), illustrata di seguito:

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

I componenti vengono suddivisi come segue:

  • marcatore (00 00)

  • lunghezza della chiave di crittografia a blocchi (00 00 00 18)

  • la dimensione del blocco di crittografia (00 00 00 08)

  • lunghezza del tasto HMAC (00 00 00 14)

  • dimensioni del digest HMAC (00 00 00 14)

  • l'output (AB B1 - E1 0E) PRP della crittografia a blocchi e

  • output (76 EB - end)prf HMAC.

Crittografia in modalità galois/contatore + autenticazione

L'intestazione del contesto è costituita dai componenti seguenti:

  • [16 bit] Valore 00 01, ovvero un marcatore che indica "Crittografia GCM + autenticazione".

  • [32 bit] Lunghezza della chiave (in byte, big-endian) dell'algoritmo di crittografia a blocchi simmetrici.

  • [32 bit] Dimensioni nonce (in byte, big-endian) usate durante le operazioni di crittografia autenticate. (Per il sistema, questo valore è fisso a dimensioni nonce = 96 bit.

  • [32 bit] Dimensione del blocco (in byte, big-endian) dell'algoritmo di crittografia a blocchi simmetrici. Per GCM, questa impostazione è fissa a dimensione di blocco = 128 bit.

  • [32 bit] Dimensioni del tag di autenticazione (in byte, big-endian) prodotte dalla funzione di crittografia autenticata. (Per il sistema, questo valore è fisso a dimensione di tag = 128 bit).

  • [128 bit] Tag di Enc_GCM (K_E, nonce, ""), che è l'output dell'algoritmo di crittografia a blocchi simmetrici dato un input stringa vuoto e dove nonce è un vettore a 96 bit all-zero.

K_E viene derivato usando lo stesso meccanismo usato nello scenario di autenticazione CBC encryption + HMAC. Tuttavia, poiché non K_H è in gioco qui, abbiamo essenzialmente | K_H | = 0e l'algoritmo si comprime nel formato seguente.

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

Esempio: AES-256-GCM

Prima di tutto, lasciare K_E = SP800_108_CTR(prf = HMACSHA512, key = "", label = "", context = ""), dove | K_E | = 256 bits.

K_E := 22BC6F1B171C08C4AE2F27444AF8FC8B3087A90006CAEA91FDCFB47C1B8733B8

Successivamente, calcolare il tag di autenticazione di Enc_GCM (K_E, nonce, "") per AES-256-GCM specificato nonce = 096 e K_E come indicato in precedenza.

result := E7DCCE66DF855A323A6BB7BD7A59BE45

In questo modo viene eseguita l'intestazione di contesto completa seguente:

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

I componenti vengono suddivisi come segue:

  • marcatore (00 01)

  • lunghezza della chiave di crittografia a blocchi (00 00 00 20)

  • dimensioni nonce (00 00 00 0C)

  • la dimensione del blocco di crittografia (00 00 00 10)

  • dimensioni (00 00 00 10) del tag di autenticazione e

  • tag di autenticazione dall'esecuzione della crittografia (E7 DC - end)a blocchi.