7. Schémas de chiffrement (Encryption Schemes)
Aux fins de ce document, un schéma de chiffrement (Encryption Scheme) est composé d'une opération de chiffrement et d'une opération de déchiffrement, où l'opération de chiffrement génère un texte chiffré à partir d'un message en utilisant la clé publique RSA du destinataire, et l'opération de déchiffrement récupère un message à partir d'un texte chiffré en utilisant la clé privée RSA correspondante du destinataire.
Les schémas de chiffrement peuvent être appliqués à une variété de scénarios d'application. Une application typique est le protocole d'établissement de clé (Key Establishment Protocol), où le message contient du matériel de clé qui doit être transféré en toute confidentialité d'une partie à une autre. Par exemple, PKCS #7 [RFC2315] utilise de tels protocoles pour transférer une clé de chiffrement de contenu d'un expéditeur à un destinataire ; les schémas de chiffrement définis dans ce document conviennent pour être utilisés comme algorithmes de chiffrement de clé dans ce contexte.
Ce document spécifie deux schémas de chiffrement : RSAES-OAEP et RSAES-PKCS1-v1_5. Les nouvelles applications DOIVENT (REQUIRED) prendre en charge RSAES-OAEP ; RSAES-PKCS1-v1_5 n'est inclus que pour la compatibilité avec les applications existantes.
Les schémas de chiffrement présentés ici suivent un modèle général similaire à celui utilisé dans IEEE 1363 [IEEE1363], combinant des primitives de chiffrement et de déchiffrement avec une méthode d'encodage pour le chiffrement. L'opération de chiffrement applique une opération d'encodage de message au message pour produire un message encodé, qui est ensuite converti en un représentant de message entier. La primitive de chiffrement est appliquée au représentant de message pour produire le texte chiffré. Inversement, l'opération de déchiffrement applique la primitive de déchiffrement au texte chiffré pour récupérer le représentant de message, qui est ensuite converti en une chaîne d'octets de message encodé. Une opération de décodage de message est appliquée au message encodé pour récupérer le message et vérifier l'exactitude du déchiffrement.
Pour éviter les faiblesses d'implémentation liées à la manière dont les erreurs sont gérées dans l'opération de décodage (voir [BLEICHENBACHER] et [MANGER]), les opérations d'encodage et de décodage de RSAES-OAEP et RSAES-PKCS1-v1_5 sont intégrées dans les spécifications des schémas de chiffrement respectifs, plutôt que d'être définies dans des spécifications séparées. Les deux schémas de chiffrement sont compatibles avec les schémas correspondants dans PKCS #1 v2.1.
7.1. RSAES-OAEP
RSAES-OAEP combine les primitives RSAEP et RSADP (Section 5.1) avec la méthode d'encodage EME-OAEP (intégrée dans cette section). Il est basé sur la méthode de rembourrage optimal de chiffrement asymétrique (Optimal Asymmetric Encryption Padding, OAEP) de Bellare et Rogaway, introduite pour la première fois dans [OAEP]. EME-OAEP est une variante unidirectionnelle de EME-OAEP dans IEEE 1363 [IEEE1363].
Le schéma n'est pas déterministe : pour une clé publique et un message donnés, de nombreux textes chiffrés possibles peuvent être générés.
RSAES-OAEP est recommandé pour les nouvelles applications. RSAES-OAEP peut être utilisé comme alternative préférable à RSAES-PKCS1-v1_5 dans toute application.
La sécurité de ce schéma est basée sur la difficulté de deux fonctions : le problème RSA et le modèle d'oracle aléatoire de la fonction de génération de masque (Mask Generation Function, MGF). Les propriétés de sécurité de ces deux fonctions sont incarnées dans une preuve de théorème montrant que la difficulté d'utiliser RSAES-OAEP contre une attaque par texte chiffré choisi (Chosen Ciphertext Attack) est essentiellement aussi difficile que de résoudre le problème RSA, à condition que le MGF se comporte comme un oracle aléatoire (Random Oracle).
7.1.1. Opération de chiffrement (Encryption Operation)
RSAES-OAEP-ENCRYPT ((n, e), M, L)
Entrée (Input):
- (n, e): clé publique RSA du destinataire (k désigne la longueur en octets du module)
- M: message à chiffrer, une chaîne d'octets de longueur au plus k - 2hLen - 2, où hLen est la longueur de sortie en octets de la fonction de hachage Hash
- L: étiquette optionnelle (Label) associée à l'opération de chiffrement ; la valeur par défaut est la chaîne vide
Sortie (Output):
- C: texte chiffré, une chaîne d'octets de longueur k
Erreurs (Errors):
- "message too long" (message trop long)
- "label too long" (étiquette trop longue)
Hypothèse (Assumption): La clé publique RSA (n, e) est valide
Étapes (Steps):
-
Vérification de longueur : Si la longueur de L est supérieure à la limite d'entrée pour la fonction de génération de masque (qui est 2^61 - 1 octets), sortir "label too long" et arrêter.
-
Encodage EME-OAEP :
- Si la longueur de M est supérieure à k - 2hLen - 2 octets, sortir "message too long" et arrêter.
- Soit lHash = Hash(L), une chaîne d'octets de longueur hLen.
- Générer une chaîne de rembourrage PS composée de k - mLen - 2hLen - 2 octets zéro et d'un seul octet de valeur 0x01.
- Concaténer lHash, PS, l'octet unique 0x01 et le message M pour former le bloc de données DB : DB = lHash || PS || 0x01 || M
- Générer une chaîne d'octets aléatoire seed de longueur hLen.
- Soit dbMask = MGF(seed, k - hLen - 1).
- Soit maskedDB = DB ⊕ dbMask.
- Soit seedMask = MGF(maskedDB, hLen).
- Soit maskedSeed = seed ⊕ seedMask.
- Concaténer un seul octet de valeur 0x00, maskedSeed et maskedDB pour former le message encodé EM : EM = 0x00 || maskedSeed || maskedDB
-
Chiffrement RSA :
- Convertir le message encodé EM en un représentant de message entier m : m = OS2IP(EM)
- Appliquer la primitive de chiffrement RSAEP : c = RSAEP((n, e), m)
- Convertir le représentant de texte chiffré c en un texte chiffré C de longueur k : C = I2OSP(c, k)
-
Sortir le texte chiffré C.
7.1.2. Opération de déchiffrement (Decryption Operation)
RSAES-OAEP-DECRYPT (K, C, L)
Entrée (Input):
- K: clé privée RSA du destinataire
- C: texte chiffré à déchiffrer, une chaîne d'octets de longueur k, où k est la longueur en octets du module RSA n
- L: étiquette optionnelle dont la valeur est associée à l'étiquette lors de l'opération de chiffrement qui a généré le texte chiffré ; la valeur par défaut est la chaîne vide
Sortie (Output):
- M: message, une chaîne d'octets de longueur au plus k - 2hLen - 2
Erreur (Error):
- "decryption error" (erreur de déchiffrement)
Étapes (Steps):
-
Vérification de longueur : Si la longueur de L est supérieure à la limite d'entrée, sortir "decryption error" et arrêter. Si la longueur du texte chiffré C n'est pas de k octets (ou si k < 2hLen + 2), sortir "decryption error" et arrêter.
-
Déchiffrement RSA :
- Convertir le texte chiffré C en un représentant de texte chiffré entier c : c = OS2IP(C)
- Appliquer la primitive de déchiffrement RSADP : m = RSADP(K, c). Si RSADP sort "ciphertext representative out of range", sortir "decryption error" et arrêter.
- Convertir le représentant de message m en un message encodé EM de longueur k : EM = I2OSP(m, k)
-
Décodage EME-OAEP :
- Soit lHash = Hash(L).
- Séparer EM en un seul octet Y, une chaîne d'octets maskedSeed de longueur hLen, et une chaîne d'octets maskedDB de longueur k - hLen - 1 : EM = Y || maskedSeed || maskedDB
- Soit seedMask = MGF(maskedDB, hLen).
- Soit seed = maskedSeed ⊕ seedMask.
- Soit dbMask = MGF(seed, k - hLen - 1).
- Soit DB = maskedDB ⊕ dbMask.
- Séparer DB en une chaîne d'octets lHash' de longueur hLen, une chaîne de rembourrage PS (possiblement vide) composée d'octets de valeur 0x00, un seul octet de valeur 0x01, et un message M : DB = lHash' || PS || 0x01 || M. S'il n'y a pas d'octet de valeur 0x01 pour séparer PS et M, si lHash n'est pas égal à lHash', ou si Y est non nul, sortir "decryption error" et arrêter.
-
Sortir le message M.
Note : L'implémentation doit être effectuée avec soin pour éviter que l'implémentation ne fournisse par inadvertance des informations utiles à un adversaire. En particulier, les messages d'erreur ne doivent pas révéler si un octet dans EM ou d'autres octets dans DB ne sont pas de la forme attendue.
7.2. RSAES-PKCS1-v1_5
RSAES-PKCS1-v1_5 combine les primitives RSAEP et RSADP (Section 5.1) avec la méthode d'encodage EME-PKCS1-v1_5. Il n'est inclus que pour la compatibilité avec les applications existantes ; pour les nouvelles applications, l'utilisation de RSAES-OAEP est recommandée.
La sécurité de RSAES-PKCS1-v1_5 dépend de la difficulté du problème RSA. Des faiblesses potentielles connues (voir [BLEICHENBACHER]) existent, donc les nouvelles applications devraient utiliser RSAES-OAEP.
7.2.1. Opération de chiffrement (Encryption Operation)
RSAES-PKCS1-V1_5-ENCRYPT ((n, e), M)
Les entrées, sorties et étapes sont similaires à RSAES-OAEP, mais utilisent l'encodage EME-PKCS1-v1_5
7.2.2. Opération de déchiffrement (Decryption Operation)
RSAES-PKCS1-V1_5-DECRYPT (K, C)
Les entrées, sorties et étapes sont similaires à RSAES-OAEP, mais utilisent le décodage EME-PKCS1-v1_5
Remarque de sécurité importante : Les messages d'erreur de déchiffrement ne doivent pas distinguer différents types d'erreurs pour prévenir l'attaque par texte chiffré choisi de Bleichenbacher.