Partager via


Dérivation de sous-clé et chiffrement authentifié dans ASP.NET Core

La plupart des clés de l’anneau de clés contiennent une forme d’entropie et auront des informations algorithmiques indiquant « Chiffrement en mode CBC + validation HMAC » ou « Chiffrement GCM + validation ». Dans ces cas, nous faisons référence à l’entropie incorporée comme matériau de clé principale (ou KM) pour cette clé, et nous effectuons une fonction de dérivation de clé pour dériver les clés qui seront utilisées pour les opérations de chiffrement réelles.

Note

Les clés sont abstraites et une implémentation personnalisée peut ne pas se comporter comme ci-dessous. Si la clé fournit sa propre implémentation de IAuthenticatedEncryptor plutôt que d’utiliser l’une de nos usines intégrées, le mécanisme décrit dans cette section ne s’applique plus.

Données authentifiées supplémentaires et dérivation de sous-clé

L’interface IAuthenticatedEncryptor sert d’interface principale pour toutes les opérations de chiffrement authentifiées. Sa Encrypt méthode accepte deux mémoires tampons : le texte en clair et les données authentifiées supplémentaires (AAD). Le flux de contenu en texte clair n’a pas changé l’appel, IDataProtector.Protectmais l’AAD est généré par le système et se compose de trois composants :

  1. L'en-tête magique 32 bits 09 F0 C9 F0 qui identifie cette version du système de protection des données.

  2. ID de clé 128 bits.

  3. Chaîne de longueur variable formée à partir de la chaîne d’objectif qui a créé l’opération IDataProtector qui effectue cette opération.

Étant donné que L’AAD est unique pour le tuple des trois composants, nous pouvons l’utiliser pour dériver de nouvelles clés à partir de KM au lieu d’utiliser KM lui-même dans toutes nos opérations de chiffrement. Pour chaque appel à IAuthenticatedEncryptor.Encrypt, le processus de dérivation de clé suivant a lieu :

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

Ici, nous appelons le KDF de NIST SP800-108 en mode compteur (voir NIST SP800-108, Sec. 5.1) avec les paramètres suivants :

  • Clé de dérivation de clé (KDK) = K_M

  • PRF = HMACSHA512

  • label = donnéesAuthentifiéesSupplémentaires

  • context = contextHeader || keyModifier

L’en-tête de contexte est de longueur variable et sert essentiellement d’empreinte numérique des algorithmes pour lesquels nous dérivons K_E et K_H. Le modificateur de clé est une chaîne de 128 bits générée de manière aléatoire pour chaque appel à Encrypt, et sert à garantir avec une très forte probabilité que KE et KH soient uniques pour cette opération de chiffrement d’authentification spécifique, même si toutes les autres entrées de la KDF sont constantes.

Pour le chiffrement en mode CBC + opérations de validation HMAC, | K_E | est la longueur de la clé de chiffrement de bloc symétrique et | K_H | est la taille de synthèse de la routine HMAC. Pour les opérations de chiffrement GCM + validation, | K_H | = 0.

Chiffrement en mode CBC + validation HMAC

Une fois K_E généré via le mécanisme ci-dessus, nous générons un vecteur d’initialisation aléatoire et exécutons l’algorithme de chiffrement de bloc symétrique pour déchiffrer le texte en clair. Le vecteur d’initialisation et le texte chiffré sont ensuite exécutés via la routine HMAC initialisée avec la clé K_H pour produire le MAC. Ce processus et la valeur de retour sont représentées graphiquement ci-dessous.

Processus en mode CBC et retour

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

Note

L’implémentation IDataProtector.Protectprécède l’en-tête magique et l’ID de clé pour la sortie avant de le retourner à l’appelant. Étant donné que l’en-tête magique et l’ID de clé font implicitement partie d’AAD, et que le modificateur de clé est alimenté en tant qu’entrée à la KDF, cela signifie que chaque octet de la charge utile retournée finale est authentifié par le MAC.

Chiffrement Galois/Counter Mode + validation

Une fois K_E généré via le mécanisme ci-dessus, nous générons un nonce de 96 bits aléatoire et exécutons l’algorithme de chiffrement de bloc symétrique pour chiffrer le texte en clair et produire la balise d’authentification de 128 bits.

Processus en mode GCM et retour

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

Note

Même si GCM prend en charge en mode natif le concept d’AAD, nous alimentons toujours AAD uniquement à la fonction KDF d’origine, en choisissant de passer une chaîne vide dans GCM pour son paramètre AAD. La raison est double. Tout d’abord, pour prendre en charge l’agilité , nous ne voulons jamais utiliser K_M directement comme clé de chiffrement. En outre, GCM impose des exigences d’unicité très strictes sur ses entrées. La probabilité que la routine de chiffrement GCM soit jamais appelée sur deux ensembles distincts ou plus de données d’entrée avec la même paire (clé, nonce) ne doit pas dépasser 2^-32. Si nous corrigeons K_E, nous ne pouvons effectuer plus de 2^32 opérations de chiffrement avant d'atteindre la limite de 2^-32. Cela peut sembler un très grand nombre d’opérations, mais un serveur web à trafic élevé peut traiter 4 milliards de requêtes en quelques jours, bien dans la durée de vie normale de ces clés. Pour rester conforme à la limite de probabilité 2^-32, nous continuons à utiliser un modificateur de clé 128 bits et un nonce 96 bits, ce qui étend radicalement le nombre d’opérations utilisables pour n’importe quel donné K_M. Par souci de simplicité de conception, nous partageons le chemin du code KDF entre les opérations CBC et GCM, et étant donné que AAD est déjà considéré dans la KDF, il n’est pas nécessaire de le transférer à la routine GCM.