Condividi tramite


Derivazione della sottochiave e crittografia autenticata in ASP.NET Core

La maggior parte delle chiavi nell'anello delle chiavi conterrà una forma di entropia e avrà informazioni algoritmiche che indicano "Crittografia in modalità CBC + convalida HMAC" o "Crittografia GCM + convalida". In questi casi, si fa riferimento all'entropia incorporata come materiale per la chiave master (o km) per questa chiave e si esegue una funzione di derivazione della chiave per derivare le chiavi che verranno usate per le operazioni di crittografia effettive.

Nota

Le chiavi sono astratte e un'implementazione personalizzata potrebbe non comportarsi come indicato di seguito. Se la chiave fornisce la propria implementazione anziché IAuthenticatedEncryptor usare una delle factory predefinite, il meccanismo descritto in questa sezione non si applica più.

Dati autenticati aggiuntivi e derivazione della sottochiave

L'interfaccia IAuthenticatedEncryptor funge da interfaccia principale per tutte le operazioni di crittografia autenticate. Il Encrypt metodo accetta due buffer: testo non crittografato e additionalAuthenticatedData (AAD). Il flusso del contenuto di testo non crittografato ha modificato la chiamata a IDataProtector.Protect, ma L'AAD viene generato dal sistema ed è costituito da tre componenti:

  1. Intestazione magic a 32 bit 09 F0 F9 F0 che identifica questa versione del sistema di protezione dei dati.

  2. ID chiave a 128 bit.

  3. Stringa di lunghezza variabile formata dalla catena di scopi che ha creato l'oggetto IDataProtector che esegue questa operazione.

Poiché AAD è univoco per la tupla di tutti e tre i componenti, è possibile usarla per derivare nuove chiavi dal Km invece di usare il servizio di gestione delle chiavi in tutte le operazioni di crittografia. Per ogni chiamata a IAuthenticatedEncryptor.Encrypt, viene eseguito il processo di derivazione della chiave seguente:

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

In questo caso viene chiamato NIST SP800-108 KDF in modalità contatore (vedere NIST SP800-108, Sec. 5.1) con i parametri seguenti:

  • Chiave di derivazione della chiave (KDK) = K_M

  • PRF = HMACSHA512

  • label = additionalAuthenticatedData

  • context = contextHeader || keyModifier

L'intestazione di contesto è di lunghezza variabile e essenzialmente funge da identificazione personale degli algoritmi per cui si sta derivando K_E e K_H. Il modificatore di chiave è una stringa a 128 bit generata in modo casuale per ogni chiamata a Encrypt e serve a garantire con una probabilità eccessiva che KE e KH siano univoci per questa specifica operazione di crittografia dell'autenticazione, anche se tutti gli altri input per KDF sono costanti.

Per le operazioni di crittografia in modalità CBC + HMAC, | K_E | è la lunghezza della chiave di crittografia a blocchi simmetrici ed | K_H | è la dimensione digest della routine HMAC. Per le operazioni di crittografia e convalida GCM, | K_H | = 0.

Crittografia in modalità CBC + convalida HMAC

Una volta K_E generato tramite il meccanismo precedente, viene generato un vettore di inizializzazione casuale ed eseguito l'algoritmo di crittografia a blocchi simmetrici per crittografare il testo non crittografato. Il vettore di inizializzazione e il testo crittografato vengono quindi eseguiti tramite la routine HMAC inizializzata con la chiave K_H per produrre il MAC. Questo processo e il valore restituito sono rappresentati graficamente sotto.

CBC-mode process and return

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

Nota

L'implementazione IDataProtector.Protect anteporrà l'intestazione magic e l'ID chiave all'output prima di restituirlo al chiamante. Poiché l'intestazione magic e l'ID della chiave fanno parte implicitamente di AAD e poiché il modificatore di tasti viene fornito come input per KDF, ciò significa che ogni singolo byte del payload restituito finale viene autenticato dal MAC.

Crittografia in modalità galois/contatore + convalida

Una volta K_E generato tramite il meccanismo precedente, viene generato un nonce a 96 bit casuale ed eseguito l'algoritmo di crittografia a blocchi simmetrici per crittografare il testo non crittografato e produrre il tag di autenticazione a 128 bit.

GCM-mode process and return

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

Nota

Anche se GCM supporta in modo nativo il concetto di AAD, stiamo ancora inviando AAD solo alla KDF originale, optando per passare una stringa vuota in GCM per il parametro AAD. Il motivo è due volte. Prima di tutto, per supportare l'agilità non si vuole mai usare K_M direttamente come chiave di crittografia. GCM impone inoltre requisiti di univocità molto rigorosi per gli input. La probabilità che la routine di crittografia GCM venga richiamata su due o più set distinti di dati di input con la stessa coppia (chiave, nonce) non deve superare 2^-32. Se non K_E è possibile eseguire più di 2^32 operazioni di crittografia prima di eseguire il limite di 2^-32. Questo potrebbe sembrare un numero molto elevato di operazioni, ma un server Web ad alto traffico può superare 4 miliardi di richieste in pochi giorni, ben entro la normale durata di queste chiavi. Per mantenere la conformità del limite di probabilità 2^-32, continuiamo a usare un modificatore di chiave a 128 bit e un nonce a 96 bit, che estende radicalmente il numero di operazioni utilizzabili per qualsiasi dato K_M. Per semplicità di progettazione, il percorso del codice KDF viene condiviso tra le operazioni CBC e GCM e poiché AAD è già considerato in KDF non è necessario inoltrarlo alla routine GCM.