RFC 6979 - Utilisation déterministe de l'algorithme de signature numérique (DSA) et de l'algorithme de signature numérique à courbe elliptique (ECDSA)
- Statut: Informational
- Publié: August 2013
- Stream: INDEPENDENT
- Errata: Pas d'errata
Résumé
Ce document définit une procédure de génération de signature numérique déterministe. Ces signatures sont compatibles avec les signatures numériques standard Digital Signature Algorithm (DSA) et Elliptic Curve Digital Signature Algorithm (ECDSA) et peuvent être traitées avec des vérificateurs non modifiés, qui n'ont pas besoin d'être au courant de la procédure décrite ici. Les signatures déterministes conservent les caractéristiques de sécurité cryptographique associées aux signatures numériques mais peuvent être mises en œuvre plus facilement dans divers environnements, car elles n'ont pas besoin d'accéder à une source de randomité de haute qualité.
Statut de ce mémo
Ce document n'est pas une spécification de la piste des normes Internet; il est publié à titre informatif.
Il s'agit d'une contribution à la série RFC, indépendamment de tout autre flux RFC. L'éditeur RFC a choisi de publier ce document à sa discrétion et ne fait aucune déclaration sur sa valeur pour la mise en œuvre ou le déploiement. Les documents approuvés pour publication par l'éditeur RFC ne sont pas candidats à un quelconque niveau de norme Internet; voir la section 2 de RFC 5741.
Les informations sur l'état actuel de ce document, les errata éventuels et la façon de fournir des commentaires peuvent être obtenus à l'adresse http://www.rfc-editor.org/info/rfc6979.
Avis de droit d'auteur
Copyright (c) 2013 IETF Trust et les personnes identifiées comme auteurs du document. Tous droits réservés.
Ce document est soumis à BCP 78 et aux dispositions légales de l'IETF Trust relatives aux documents IETF (http://trustee.ietf.org/license-info) en vigueur à la date de publication de ce document. Veuillez examiner ces documents attentivement, car ils décrivent vos droits et restrictions concernant ce document.
Table des matières
- 1. Introduction
- 2. Notations DSA et ECDSA
- 3. DSA et ECDSA déterministes
- 4. Considérations de sécurité
- 5. Statut de la propriété intellectuelle
- 6. Références
- Annexe A. Exemples
1. Introduction
DSA [FIPS-186-4] et ECDSA [X9.62] sont deux schémas de signature numérique standard. Ils fournissent l'intégrité des données et l'authenticité vérifiable dans divers protocoles.
Une caractéristique de DSA et ECDSA est qu'ils doivent produire, pour chaque génération de signature, une valeur aléatoire fraîche (ci-après désignée par k). Pour une sécurité efficace, k DOIT être choisi de manière aléatoire et uniforme parmi un ensemble d'entiers modulaires, en utilisant un processus cryptographiquement sécurisé. Même de légers biais dans ce processus peuvent être transformés en attaques contre les schémas de signature.
La nécessité d'une source cryptographiquement sécurisée de randomité s'avère être un obstacle au déploiement des schémas de signature DSA et ECDSA dans certaines architectures dans lesquelles la génération de nombres aléatoires sécurisés est difficile, en particulier les systèmes embarqués tels que les cartes à puce. Dans ces systèmes, l'algorithme de signature RSA, utilisé comme spécifié dans Public-Key Cryptography Standards (PKCS) #1 [RFC3447] (avec le rembourrage "type 1", pas le Probabilistic Signature Scheme (PSS)) et ISO 9796-2 [ISO-9796-2], est souvent préféré, même s'il est plus coûteux en calcul, car RSA (avec de tels schémas de rembourrage) est déterministe et ne nécessite donc pas de source de randomité.
La nature randomisée de DSA et ECDSA rend également les implémentations plus difficiles à tester. Les tests automatiques ne peuvent pas détecter de manière fiable si l'implémentation utilise une source de randomité de qualité suffisamment élevée. Cela rend le processus d'implémentation plus vulnérable aux échecs catastrophiques, souvent découverts après que le système a été déployé et attaqué avec succès.
Il est possible de transformer DSA et ECDSA en schémas déterministes en utilisant un processus déterministe pour générer la valeur "aléatoire" k. Ce processus DOIT remplir certaines caractéristiques cryptographiques afin de maintenir les propriétés de vérifiabilité et d'infalsifiabilité attendues des schémas de signature; à savoir, pour quiconque ne connaît pas la clé privée de signature, le mappage des messages d'entrée aux valeurs k correspondantes DOIT être computationnellement indiscernable de ce qu'une fonction choisie aléatoirement et uniformément (de l'ensemble des messages à l'ensemble des valeurs k possibles) retournerait.
Ce document décrit une telle procédure. Elle présente les caractéristiques suivantes:
-
Les signatures produites restent entièrement compatibles avec DSA et ECDSA ordinaires. Les entités qui vérifient les signatures n'ont pas besoin d'être modifiées ou même d'être au courant du processus utilisé pour générer k.
-
La génération de paires de clés n'est pas modifiée. Les clés privées existantes peuvent être utilisées avec DSA et ECDSA déterministes.
-
L'utilisation de DSA et ECDSA déterministes n'implique aucune exigence de stockage supplémentaire de valeur secrète ou publique.
-
DSA et ECDSA déterministes peuvent être appliqués sur les mêmes entrées que DSA et ECDSA ordinaires, à savoir une valeur de hachage calculée sur le message qui doit être signé, avec une fonction de hachage cryptographiquement sécurisée.
Certains choix relativement arbitraires ont été pris dans la définition de (EC)DSA déterministe tel que spécifié dans ce document; cela a été fait afin de le rendre aussi universellement applicable que possible, de manière à maximiser l'utilité des vecteurs de test inclus. Voir la section 3.6 pour une discussion de certaines variantes possibles.
Il convient de noter que la génération de paires de clés nécessite toujours une source de randomité. Dans les systèmes embarqués où la qualité de la randomité est un problème, il peut souvent être organisé que la génération de paires de clés se produise dans des conditions plus contrôlées (par exemple, lors d'une procédure d'initialisation spéciale de carte à puce ou sous le contrôle physique d'agents assermentés) ou la clé pourrait même être générée ailleurs et importée dans le dispositif. DSA et ECDSA déterministes ne traitent que du besoin de randomité au moment de la génération de signature.
1.1. Langage des exigences
Les mots-clés "DOIT" (MUST), "NE DOIT PAS" (MUST NOT), "REQUIS" (REQUIRED), "DEVRA" (SHALL), "NE DEVRA PAS" (SHALL NOT), "DEVRAIT" (SHOULD), "NE DEVRAIT PAS" (SHOULD NOT), "RECOMMANDÉ" (RECOMMENDED), "PEUT" (MAY) et "OPTIONNEL" (OPTIONAL) dans ce document doivent être interprétés comme décrit dans RFC 2119 [RFC2119].
2. Notations DSA et ECDSA
Dans cette section, nous décrivons succinctement DSA et ECDSA et définissons nos notations. Les spécifications complètes pour DSA et ECDSA peuvent être trouvées dans [FIPS-186-4] et [X9.62], respectivement.
2.1. Paramètres de clé
DSA et ECDSA fonctionnent sur un grand groupe de taille première, dans lequel l'opération de groupe est facile à calculer, mais le logarithme discret est computationnellement infaisable avec la technologie existante et prévisible. La définition du groupe est appelée les "paramètres de clé". Les paramètres de clé peuvent être partagés entre différentes paires de clés sans effet néfaste sur la sécurité; c'est le cas habituel avec ECDSA en particulier.
DSA utilise les paramètres de clé suivants:
p
: un grand nombre premier (au moins 1024 bits)
q
: un nombre premier suffisamment grand (au moins 160 bits) qui est également un diviseur de p-1
g
: un générateur pour le sous-groupe multiplicatif d'ordre q des entiers modulo p
Le groupe sur lequel DSA sera calculé se compose des valeurs 'g^j mod p', où '^' désigne l'exponentiation et j varie de 0 à q-1 (inclus). La taille du groupe est q.
ECDSA utilise les paramètres de clé suivants:
E
: une courbe elliptique, définie sur un corps fini donné
q
: un nombre premier suffisamment grand (au moins 160 bits) qui est un diviseur de l'ordre de la courbe
G
: un point de E, d'ordre q
Le groupe sur lequel ECDSA sera calculé se compose des points de courbe jG (multiplication du point G par l'entier j) où j varie de 0 à q-1. G est tel que qG = 0 (le "point à l'infini" sur la courbe E). La taille du groupe est q. Notez que ces notations diffèrent légèrement de celles décrites dans [X9.62]; nous les utilisons afin de correspondre à celles utilisées pour DSA.
2.2. Paires de clés
Une clé privée DSA ou ECDSA est un entier x pris modulo q. Les normes pertinentes prescrivent que x ne doit pas être 0; par conséquent, x est un entier dans la plage [1, q-1].
Une clé publique DSA ou ECDSA est calculée à partir de la clé privée x et des paramètres de clé:
-
Pour DSA, la clé publique est l'entier: y = g^x mod p
-
Pour ECDSA, la clé publique est le point de courbe: U = xG
2.3. Conversions d'entiers
Soit qlen la longueur binaire de q. qlen est le plus petit entier tel que q est inférieur à 2^qlen. C'est la taille de la représentation binaire de q sans bit de signe (notez que q, étant un grand nombre premier, est impair, évitant ainsi toute ambiguïté sur la longueur de tout entier égal à une puissance de 2). Nous définissons cinq fonctions de conversion, qui fonctionnent sur des chaînes de bits, d'octets et des entiers modulo q. qlen est le paramètre principal pour ces conversions.
Dans les sous-sections suivantes, nous utilisons deux autres longueurs, appelées blen et rlen. rlen est égal à qlen, arrondi au multiple suivant de 8 (si qlen est déjà un multiple de 8, alors rlen est égal à qlen; sinon, rlen est légèrement plus grand, jusqu'à qlen+7). Notez que rlen n'est pas lié à la valeur r, la première moitié d'une signature générée. blen est la longueur (en bits) d'une séquence d'entrée de bits et peut varier entre les appels. blen peut être inférieur, égal ou supérieur à qlen.
2.3.1. Bits et octets
Formellement, toutes les opérations sont définies sur des séquences de bits. Une séquence est ordonnée; le premier bit est dit le plus à gauche, tandis que le dernier bit est le plus à droite.
Sur la plupart des systèmes logiciels, les bits sont regroupés en octets (séquences de huit bits). Les données binaires, par exemple la sortie d'une fonction de hachage, sont disponibles sous forme de séquence d'octets. Lorsque cela est applicable, nous considérons que les bits dans un octet sont ordonnés du plus significatif au moins significatif: le premier bit (le plus à gauche) dans un octet a une valeur numérique de 128, tandis que le dernier (le plus à droite) a une valeur numérique de 1.
2.3.2. Chaîne de bits vers entier
La transformation bits2int prend en entrée une séquence de blen bits et produit un entier non négatif qui est inférieur à 2^qlen. Elle consiste en les étapes suivantes:
-
La séquence est d'abord tronquée ou étendue à la longueur qlen:
-
si qlen < blen, alors les qlen bits les plus à gauche sont conservés, et les bits suivants sont écartés;
-
sinon, qlen-blen bits (de valeur zéro) sont ajoutés à gauche de la séquence (c'est-à-dire avant les bits d'entrée dans l'ordre de séquence).
-
-
La séquence résultante est ensuite convertie en une valeur entière en utilisant la convention big-endian: si les bits d'entrée sont appelés b_0 (le plus à gauche) à b_(qlen-1) (le plus à droite), alors la valeur résultante est:
b_02^(qlen-1) + b_12^(qlen-2) + ... + b_(qlen-1)*2^0
La transformation bits2int peut également être décrite de la manière suivante: la séquence de bits d'entrée (de longueur blen) est transformée en un entier en utilisant la convention big-endian. Ensuite, si blen est supérieur à qlen, l'entier résultant est divisé par deux à la puissance blen-qlen (division euclidienne: le reste est écarté); dans de nombreuses implémentations logicielles d'arithmétique sur de grands entiers, cette division équivaut à un "décalage à droite" de blen-qlen bits.
2.3.3. Entier vers chaîne d'octets
Une valeur entière x inférieure à q (et, en particulier, une valeur qui a été prise modulo q) peut être convertie en une séquence de rlen bits, où rlen = 8*ceil(qlen/8). C'est la séquence de bits obtenue par encodage big-endian. En d'autres termes, les bits de séquence x_i (pour i allant de 0 à rlen-1) sont tels que:
x = x_02^(rlen-1) + x_12^(rlen-2) + ... + x_(rlen-1)
Nous appelons cette transformation int2octets. Puisque rlen est un multiple de 8 (le plus petit multiple de 8 qui n'est pas inférieur à qlen), alors la séquence de bits résultante est également une séquence d'octets, d'où le nom.
2.3.4. Chaîne de bits vers chaîne d'octets
La transformation bits2octets prend en entrée une séquence de blen bits et produit une séquence de rlen bits. Elle consiste en les étapes suivantes:
-
La séquence d'entrée b est convertie en une valeur entière z1 par la transformation bits2int:
z1 = bits2int(b)
-
z1 est réduit modulo q, donnant z2 (un entier entre 0 et q-1, inclus):
z2 = z1 mod q
Notez que puisque z1 est inférieur à 2^qlen, cette réduction modulaire peut être implémentée avec une simple soustraction conditionnelle: z2 = z1-q si cette valeur est non négative; sinon, z2 = z1.
-
z2 est transformé en une séquence d'octets (une séquence de rlen bits) en appliquant int2octets.
2.3.5. Utilisation
Il convient de noter que int2octets n'est pas l'inverse de bits2int, même pour les séquences d'entrée de longueur qlen: int2octets ajoutera quelques bits à gauche, tandis que bits2int écartera quelques bits à droite. int2octets est l'inverse de bits2int uniquement lorsque qlen est un multiple de 8 et que les séquences de bits ont déjà la longueur qlen.
bits2int est utilisé pendant la génération et la vérification de signature dans DSA et ECDSA standard pour transformer une valeur de hachage (calculée sur le message d'entrée) en un entier modulo q. C'est-à-dire que l'entier obtenu par bits2int est ensuite réduit modulo q; puisque cet entier est inférieur à 2^qlen, cette réduction peut être effectuée avec au plus une soustraction.
int2octets est défini sous le nom "Integer-to-OctetString" dans la section 2.3.7 de SEC 1 [SEC1]. Il est utilisé dans la spécification de l'encodage d'une clé privée ECDSA (x) dans une structure basée sur ASN.1.
bits2octets n'est pas utilisé dans DSA ou ECDSA standard. Nous l'utiliserons dans la spécification de (EC)DSA déterministe.
2.4. Génération de signature
La génération de signature utilise une fonction de hachage cryptographique H et un message d'entrée m. Le message est d'abord traité par H, produisant la valeur H(m), qui est une séquence de bits de longueur hlen. Normalement, H est choisi de sorte que sa longueur de sortie hlen soit à peu près égale à qlen, puisque la sécurité globale du schéma de signature dépendra du plus petit de hlen et qlen; cependant, les normes pertinentes prennent en charge toutes les combinaisons de hlen et qlen.
Les étapes suivantes sont ensuite appliquées:
-
H(m) est transformé en un entier modulo q en utilisant la transformation bits2int et une réduction modulaire supplémentaire:
h = bits2int(H(m)) mod q
Comme cela a été noté dans la description de bits2octets, la réduction modulaire supplémentaire n'est pas plus qu'une soustraction conditionnelle.
-
Une valeur aléatoire modulo q, appelée k, est générée. Cette valeur ne doit pas être 0; par conséquent, elle se situe dans la plage [1, q-1]. La plus grande partie du reste de ce document tournera autour du processus utilisé pour générer k. Dans DSA ou ECDSA ordinaire, k DEVRAIT être sélectionné par une sélection aléatoire qui choisit une valeur parmi les q-1 valeurs possibles avec une probabilité uniforme.
-
Une valeur r (modulo q) est calculée à partir de k et des paramètres de clé:
-
Pour DSA:
r = g^k mod p mod q
(L'exponentiation est effectuée modulo p, produisant un nombre entre 0 et p-1, qui est ensuite réduit davantage modulo q.)
-
Pour ECDSA: le point kG est calculé; sa coordonnée X (un membre du corps sur lequel E est défini) est convertie en un entier, qui est réduit modulo q, donnant r.
Si r s'avère être zéro, un nouveau k DEVRAIT être sélectionné et r calculé à nouveau (c'est une occurrence extrêmement improbable).
-
-
La valeur s (modulo q) est calculée:
s = (h+x*r)/k mod q
La paire (r, s) est la signature. La façon dont une signature doit être encodée n'est pas couverte par les normes DSA et ECDSA elles-mêmes; une façon courante est d'utiliser une structure ASN.1 encodée en DER (une SEQUENCE de deux INTEGER, pour r et s, dans cet ordre).
2.1. Key Parameters (Paramètres de clé)
Pour DSA, les paramètres de clé sont définis par un groupe d'ordre premier. Les paramètres sont (p, q, g), où p est un grand nombre premier, q est un diviseur premier de p-1, et g est un élément du groupe multiplicatif Z*p d'ordre q.
Pour ECDSA, les paramètres de clé sont définis par une courbe elliptique et un point de base G sur cette courbe. L'ordre de G (nombre de points dans le sous-groupe généré par G) est un grand nombre premier noté q.
2.2. Key Pairs (Paires de clés)
Une paire de clés (EC)DSA comprend une clé privée x et une clé publique. La clé privée est un entier dans l'intervalle [1, q-1]. Pour DSA, la clé publique est y = g^x mod p. Pour ECDSA, la clé publique est Q = xG (produit scalaire du point de base G avec la clé privée x).
2.3. Integer Conversions (Conversions d'entiers)
Nous avons besoin de fonctions pour convertir entre entiers, séquences de bits et séquences d'octets. Ces conversions sont essentielles pour l'implémentation de l'algorithme de génération déterministe de k.
2.3.1. Bits and Octets (Bits et octets)
Une séquence de bits est une suite ordonnée de bits. Les séquences de bits sont numérotées de gauche à droite, en commençant par le bit 0. Par exemple, dans la séquence de 8 bits "10110001", le bit 0 vaut 1, le bit 1 vaut 0, le bit 2 vaut 1, et ainsi de suite.
Un octet est une séquence de 8 bits. Une séquence d'octets est une suite ordonnée d'octets, commençant par l'octet 0 et augmentant. Dans une séquence d'octets, "octet 0" désigne l'octet le plus à gauche (premier).
2.3.2. Bit String to Integer (Chaîne de bits vers entier)
La fonction bits2int transforme une séquence de bits en un entier. Elle est définie comme suit:
La séquence est d'abord tronquée aux qlen bits les plus à gauche (si la séquence est plus longue que qlen bits) ou laissée inchangée (si sa longueur est déjà d'au plus qlen bits). La séquence est ensuite interprétée comme la représentation big-endian d'un entier.
2.3.4. Bit String to Octet String (Chaîne de bits vers chaîne d'octets)
La fonction bits2octets transforme une séquence de bits en une séquence d'octets tout en la réduisant modulo q. Elle est définie comme suit:
bits2octets(b1) = int2octets(bits2int(b1) mod q)
Cette fonction est utilisée pour traiter le message haché avant le calcul de la signature.
2.3.5. Usage (Utilisation)
Les fonctions de conversion définies ci-dessus sont utilisées dans l'algorithme de génération déterministe de k pour garantir que:
- La clé privée x est correctement encodée en séquence d'octets (int2octets)
- Le message haché H(m) est tronqué ou étendu à la bonne longueur (bits2octets)
- Les bits aléatoires générés sont correctement convertis en valeur candidate k (bits2int)
Ces conversions sont indépendantes de la représentation de champ utilisée (corps premier ou corps binaire) et fonctionnent correctement avec des groupes d'ordre q arbitraire.
2.4. Signature Generation (Génération de signature)
Le processus standard de génération de signature (EC)DSA prend en entrée:
- Les paramètres de clé (p, q, g pour DSA ou paramètres de courbe pour ECDSA)
- La clé privée x
- Le message m à signer
- Une valeur aléatoire k dans [1, q-1]
La signature est calculée comme une paire (r, s) d'entiers. La procédure déterministe décrite dans ce document remplace uniquement la génération de la valeur aléatoire k; toutes les autres étapes restent identiques au processus standard (EC)DSA.
3. DSA et ECDSA déterministes
(EC)DSA déterministe est le processus de génération d'une signature (EC)DSA sur un message d'entrée m en utilisant le processus standard de génération de signature (EC)DSA (discuté dans la section précédente), sauf que la valeur k, au lieu d'être générée aléatoirement, est obtenue par le processus décrit dans cette section.
Nous utilisons les notations décrites dans la section 2.
3.1. Blocs de construction
3.1.1. HMAC
HMAC [RFC2104] est une construction d'un code d'authentification de message utilisant une fonction de hachage et une clé secrète. Ici, nous utilisons HMAC avec la même fonction de hachage H que celle utilisée pour traiter le message d'entrée avant la génération ou la vérification de signature.
Nous désignons le processus d'application de HMAC avec la clé K sur les données V par:
HMAC_K(V)
qui retourne une séquence de bits de longueur hlen (la longueur de sortie de la fonction de hachage sous-jacente H).
3.2. Génération de k
Étant donné le message d'entrée m, le processus suivant est appliqué:
a. Traiter m par la fonction de hachage H, produisant:
h1 = H(m)
(h1 est une séquence de hlen bits).
b. Définir:
V = 0x01 0x01 0x01 ... 0x01
de sorte que la longueur de V, en bits, soit égale à 8*ceil(hlen/8). Par exemple, sur un système basé sur les octets, si H est SHA-256, alors V est défini comme une séquence de 32 octets de valeur 1. Notez que dans cette étape et toutes les étapes suivantes, nous utilisons la même fonction H que celle utilisée à l'étape 'a' pour traiter le message d'entrée; ce choix sera discuté plus en détail dans la section 3.6.
c. Définir:
K = 0x00 0x00 0x00 ... 0x00
de sorte que la longueur de K, en bits, soit égale à 8*ceil(hlen/8).
d. Définir:
K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
où '||' désigne la concaténation. En d'autres termes, nous calculons HMAC avec la clé K, sur la concaténation des éléments suivants, dans l'ordre: la valeur actuelle de V, une séquence de huit bits de valeur 0, l'encodage de la clé privée (EC)DSA x, et le message haché (éventuellement tronqué et étendu comme spécifié par la transformation bits2octets). Le résultat HMAC est la nouvelle valeur de K. Notez que la clé privée x est dans la plage [1, q-1], donc une entrée appropriée pour int2octets, produisant rlen bits de sortie, c'est-à-dire un nombre intégral d'octets (rlen est un multiple de 8).
e. Définir:
V = HMAC_K(V)
f. Définir:
K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
Notez que "l'octet interne" est 0x01 cette fois.
g. Définir:
V = HMAC_K(V)
h. Appliquer l'algorithme suivant jusqu'à ce qu'une valeur appropriée soit trouvée pour k:
-
Définir T comme la séquence vide. La longueur de T (en bits) est désignée tlen; ainsi, à ce point, tlen = 0.
-
Tant que tlen < qlen, faire ce qui suit:
V = HMAC_K(V)
T = T || V
-
Calculer:
k = bits2int(T)
Si cette valeur de k est dans la plage [1,q-1], et est appropriée pour DSA ou ECDSA (c'est-à-dire qu'elle résulte en une valeur r qui n'est pas 0; voir la section 3.4), alors la génération de k est terminée. La valeur obtenue de k est utilisée dans DSA ou ECDSA. Sinon, calculer:
K = HMAC_K(V || 0x00)
V = HMAC_K(V)
et boucler (essayer de générer un nouveau T, et ainsi de suite).
Veuillez noter que lorsque k est généré à partir de T, le résultat de bits2int est comparé à q, pas réduit modulo q. Si la valeur n'est pas entre 1 et q-1, le processus boucle. Effectuer une simple réduction modulaire induirait des biais qui seraient préjudiciables à la sécurité de la signature.
3.3. Description alternative de la génération de k
Le processus décrit dans la section précédente est en fait dérivé du générateur de nombres pseudoaléatoires "HMAC_DRBG", décrit dans [SP800-90A] et l'Annexe D de [X9.62]. En utilisant la terminologie de [SP800-90A], la génération de k peut être décrite comme suit:
a. Instancier HMAC_DRBG en utilisant HMAC paramétré avec la même fonction de hachage H que celle utilisée pour traiter le message qui doit être signé. Les paramètres d'instanciation sont:
requested_instantiation_security_strength
: Définir ce paramètre à toute valeur que l'implémentation HMAC_DRBG acceptera, lors de l'utilisation de H comme fonction de hachage de base.
prediction_resistance_flag
: Définir ce paramètre à "false".
personalization_string
: Définir ce paramètre à "Null" (la séquence de bits vide).
entropy_input
: Utiliser int2octets(x) comme chaîne d'entropie.
nonce
: Utiliser bits2octets(H(m)) comme nonce.
Notez que les deux derniers paramètres ne sont pas des paramètres de la fonction d'instanciation HMAC_DRBG en soi; au lieu de cela, ces valeurs sont demandées à la fonction interne Get_entropy_input pendant l'instanciation. Pour (EC)DSA déterministe, nous voulons que HMAC_DRBG s'exécute avec la chaîne d'entropie et le nonce que nous spécifions, sans accéder à une source d'entropie réelle.
b. Générer une valeur candidate pour k en demandant qlen bits à HMAC_DRBG et en convertissant les bits résultants en un entier avec la transformation bits2int. Répéter cette étape jusqu'à ce qu'une valeur soit obtenue, qui est non nulle, inférieure à q, et appropriée pour (EC)DSA (voir la section 3.4).
Notez que nous instancions une nouvelle instance HMAC_DRBG pour chaque processus de génération de signature. Il n'y a pas de "chaîne de personnalisation" et pas d'"entrée additionnelle" lors de la génération de bits. La fonction de réensemencement de HMAC_DRBG n'est jamais invoquée, ni de manière externe ni en conséquence du traitement interne HMAC_DRBG.
Comme montré ci-dessus, nous utilisons l'encodage de la clé privée comme "chaîne d'entropie" et le message haché (tronqué et étendu par bits2octets) comme "nonce". Dans HMAC_DRBG, la chaîne d'entropie et le nonce sont simplement concaténés dans la graine initiale; par conséquent, la division entre "entropie" et "nonce" est assez arbitraire. L'utilisation de qlen bits pour chacun devrait être compatible avec la plupart des exigences d'entrée de l'implémentation HMAC_DRBG.
3.4. Notes d'utilisation
Avec DSA ou ECDSA, la valeur k est utilisée pour calculer la première moitié de la signature, appelée r (voir la section 2.4). Les normes DSA et ECDSA imposent que, si r est zéro, alors un nouveau k DEVRAIT être sélectionné. Dans cette situation, ce document spécifie que la valeur k est "inappropriée", et le processus de génération DOIT continuer à boucler.
Cette occurrence est extrêmement improbable. En fait, cela nécessiterait un effort computationnel considérable (similaire à casser la résistance à la préimage de la fonction de hachage) pour trouver une clé privée et un message qui conduisent à une valeur zéro pour r; toucher un tel cas par pur hasard est donc jugé improbable, et un attaquant ne peut pas le forcer avec des messages soigneusement conçus. En pratique, un tel chemin de code ne sera pas déclenché et peut donc être implémenté avec peu d'optimisation.
3.5. Justification
Le processus décrit dans les sections précédentes imite le processus de génération "Approuvé" de k décrit dans l'Annexe D de [X9.62], avec le générateur de nombres pseudoaléatoires "HMAC_DRBG". La principale différence est que nous utilisons la concaténation de la clé privée x et du message haché H(m) comme graine du générateur de nombres pseudoaléatoires (PRNG). Si l'on utilise un "niveau de sécurité" de n bits, alors HMAC_DRBG DEVRAIT être utilisé avec une entropie de graine d'au moins n+64 bits; cependant, la clé x DEVRAIT également avoir été générée avec autant d'entropie, et la longueur de x est qlen, qui est au moins égale à 2*n et donc supérieure à n+64 (DSA et ECDSA, tels que spécifiés par les normes, exigent qlen >= 160). On peut alors argumenter que ECDSA déterministe remplit les exigences d'entropie de l'Annexe D de [X9.62].
Nous utilisons bits2octets(H(m)) au lieu de H(m) afin de faciliter l'intégration. En effet, de nombreux systèmes de signature existants délèguent le hachage du message; le moteur de signature (qui a accès à la clé privée) reçoit uniquement H(m). Dans certaines applications, où la bande passante des données est contrainte, seuls les premiers qlen bits de H(m) sont transférés au moteur de signature, sur la base que la transformation bits2int ignorera les bits suivants de toute façon. Possiblement, dans certains systèmes, le H(m) tronqué pourrait être réduit de manière externe modulo q, puisque c'est la première chose que (EC)DSA effectue sur le message haché. Avec la définition de bits2octets, (EC)DSA déterministe peut être appliqué avec la même entrée.
3.6. Variantes
De nombreuses parties de la spécification de (EC)DSA déterministe sont assez arbitraires. Il est possible de définir des variantes qui ne sont PAS "(EC)DSA déterministe" mais qui peuvent néanmoins être utiles dans certains contextes:
-
Il est possible d'utiliser H(m) directement, au lieu de bits2octets(H(m)), comme partie de l'entrée HMAC. Comme expliqué dans la section 3.5, nous utilisons bits2octets(H(m)) afin de faciliter l'intégration dans les systèmes qui utilisent déjà un moteur de signature (EC)DSA en lui envoyant une valeur de hachage déjà tronquée. L'utilisation du H(m) complet n'introduit aucune vulnérabilité.
-
Des données supplémentaires peuvent être ajoutées à l'entrée de HMAC, concaténées après bits2octets(H(m)):
K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
Un cas d'utilisation peut être un protocole qui nécessite un algorithme de signature non déterministe sur un système qui n'a pas accès à une source aléatoire de haute qualité. Il suffit que les données supplémentaires k' ne se répètent pas (par exemple, un compteur de signatures ou une horloge monotone) pour garantir que les signatures "d'apparence aléatoire" sont indiscernables, d'un point de vue cryptographique, des signatures (EC)DSA ordinaires. Dans la terminologie [SP800-90A], k' est l'"entrée additionnelle" qui peut être définie comme paramètre lors de la génération de bits pseudoaléatoires. Cette variante peut être considérée comme un "renforcement" de la randomité de la source des données supplémentaires k'.
-
Au lieu d'utiliser x (la clé privée) comme entrée à HMAC, il est possible d'utiliser des données secrètes supplémentaires, stockées avec la clé privée avec les mêmes mesures de sécurité. L'entropie de ces données supplémentaires DOIT être d'au moins n bits, de préférence n+64 bits ou plus, où n est le niveau de sécurité cible. Avoir des données secrètes supplémentaires peut aider à prouver formellement la sécurité de la dérandomisation, mais cela implique un coût de stockage supplémentaire et une incompatibilité avec les clés privées (EC)DSA déjà générées.
-
De même, la clé privée pourrait être une valeur z, à partir de laquelle x (la "clé privée" au sens (EC)DSA ordinaire) et une autre valeur x', à utiliser comme entrée à HMAC dans la génération de k, seraient dérivées par une fonction pseudoaléatoire (PRF) appropriée (telle que HMAC_DRBG). Cela maintiendrait les exigences de stockage de clé privée au minimum tout en fournissant une sécurité plus facilement prouvable, mais cela impacterait la génération de clé privée et ne serait pas compatible avec les paires de clés déjà générées.
-
Dans ce document, nous utilisons la même fonction de hachage H pour traiter le message d'entrée et comme paramètre à HMAC. Deux fonctions de hachage distinctes pourraient être utilisées, à condition que les deux soient adéquatement sécurisées. La sécurité globale sera limitée par la plus faible des deux fonctions de hachage, c'est-à-dire celle avec la plus petite sortie. L'utilisation d'une fonction de hachage spécifique et constante pour HMAC peut être utile pour les implémentations contraintes qui acceptent des messages hachés de manière externe, quel que soit la fonction de hachage utilisée pour cela, mais qui n'ont des ressources que pour implémenter une seule fonction de hachage pour HMAC.
Le principal inconvénient de toute variante est qu'elle cesse d'être vérifiable par rapport aux vecteurs de test publiés dans ce document.
3.2. Generation of k (Génération de k)
Étant donné le message d'entrée m, le processus suivant est appliqué:
a. Traiter m par la fonction de hachage H, ce qui donne: h1 = H(m)
b. Définir V = 0x01 0x01 0x01 ... 0x01 (de sorte que la longueur de V en bits soit égale à 8*ceil(hlen/8))
c. Définir K = 0x00 0x00 0x00 ... 0x00 (de sorte que la longueur de K en bits soit égale à 8*ceil(hlen/8))
d. Définir K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
e. Définir V = HMAC_K(V)
f. Définir K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
g. Définir V = HMAC_K(V)
h. Appliquer l'algorithme suivant jusqu'à ce qu'une valeur appropriée pour k soit trouvée. Voir RFC 6979 Section 3.2 pour les détails complets.
3.3. Alternate Description (Description alternative)
This compatibility page redirects readers to 3.3. Alternate Description (Description alternative).
3.4. Usage Notes (Notes d'utilisation)
Pour DSA ou ECDSA, la valeur k est utilisée pour calculer la première moitié de la signature, appelée r (voir Section 2.4). Les standards DSA et ECDSA stipulent que si r est nul, un nouveau k doit être sélectionné. Dans cette situation, ce document spécifie que la valeur k est "inappropriée" et le processus de génération doit continuer à boucler.
Cet événement est extrêmement improbable. En fait, il faudrait un effort de calcul considérable (similaire à briser la résistance à la préimage de la fonction de hachage) pour trouver une clé privée et un message qui conduiraient à une valeur nulle pour r. Rencontrer un tel cas par pur hasard est donc considéré comme improbable, et un attaquant ne peut pas le forcer avec des messages soigneusement conçus. En pratique, un tel chemin de code ne sera pas déclenché et peut donc être implémenté avec une optimisation minimale.
3.5. Rationale (Justification)
Le processus décrit dans les sections précédentes imite le processus de génération de k "approuvé" décrit dans l'Annexe D de [X9.62] avec le générateur de nombres pseudo-aléatoires "HMAC_DRBG". La principale différence est que nous utilisons la concaténation de la clé privée x et du message haché H(m) comme graine pour le générateur de nombres pseudo-aléatoires (PRNG). Lors de l'utilisation d'un "niveau de sécurité" de n bits, HMAC_DRBG devrait être utilisé avec une entropie de graine d'au moins n+64 bits. Cependant, la clé x devrait également avoir été générée avec autant d'entropie, et la longueur de x est qlen, qui est au moins égale à 2*n, donc supérieure à n+64 (DSA et ECDSA, tels que spécifiés par les standards, nécessitent qlen >= 160). On peut donc soutenir que ECDSA déterministe satisfait les exigences d'entropie de l'Annexe D de [X9.62].
Nous utilisons bits2octets(H(m)) au lieu de H(m) pour faciliter l'intégration. En effet, de nombreux systèmes de signature existants externalisent le hachage des messages; le moteur de signature (qui a accès à la clé privée) ne reçoit que H(m). Dans certaines applications où la bande passante des données est limitée, seuls les premiers qlen bits de H(m) sont transmis au moteur de signature, sur la base que la transformation bits2int ignorerait de toute façon les bits suivants. Éventuellement, dans certains systèmes, le H(m) tronqué pourrait être réduit modulo q en externe, car c'est la première chose que (EC)DSA fait avec le message haché. Avec la définition de bits2octets, (EC)DSA déterministe peut être appliqué avec la même entrée.
3.6. Variants (Variantes)
De nombreuses parties de la spécification de (EC)DSA déterministe sont assez arbitraires, mais le choix a été fait pour des raisons d'interopérabilité. Cette section discute de certaines variantes possibles.
La fonction de hachage H utilisée est employée dans le processus de génération de signature pour deux objectifs différents: d'abord pour traiter le message d'entrée, puis comme base pour HMAC (qui est lui-même aussi une fonction de hachage). Dans ce document, nous spécifions l'utilisation de la même fonction de hachage pour les deux usages. Cependant, cela n'est pas obligatoire; il est possible d'utiliser différentes fonctions pour ces deux rôles. Le principal inconvénient est que les vecteurs de test ne peuvent pas couvrir toutes les combinaisons; l'utilisation d'une seule fonction de hachage simplifie les tests d'interopérabilité.
Les définitions de int2octets et bits2octets conduisent à une sortie de rlen bits (c'est-à-dire qlen arrondi au multiple de 8 suivant), et elles produisent effectivement au plus qlen bits d'entropie lors de leur utilisation. Il serait possible de définir les mêmes fonctions pour qu'elles produisent exactement qlen bits; cependant, cela rendrait l'implémentation légèrement plus complexe, car de nombreux langages de programmation et frameworks tendent à travailler avec des séquences d'octets plutôt que des séquences de bits. D'un autre côté, l'arrondi de qlen ajoute au plus 7 bits, ce qui est négligeable dans le contexte d'une graine PRNG.
Dans cette spécification, nous stipulons un processus qui boucle dans des cas spéciaux où k (obtenu à partir de T via bits2int) n'est pas dans la plage appropriée, ou conduirait à générer une valeur nulle pour r. Cependant, ces deux cas ne se produisent pratiquement jamais. Le dernier cas (un r calculé de zéro) ne peut se produire qu'en raison d'un bug logiciel (par exemple, les paramètres de courbe elliptique sont corrompus pendant l'exécution du programme). Les implémentations peuvent donc choisir de traiter simplement de tels cas comme des erreurs irrécupérables et simplement d'abandonner le calcul de la signature, plutôt que de boucler.
4. Considérations de sécurité
La mise en œuvre et l'utilisation appropriées d'un algorithme de signature cryptographique nécessitent de prendre en compte de nombreux paramètres. En particulier, la génération, le stockage, le contrôle d'accès et l'élimination des clés privées sont des opérations sensibles, que ce document n'aborde d'aucune manière. (EC)DSA déterministe montre comment atteindre les caractéristiques de sécurité d'un schéma de signature DSA ou ECDSA standard tout en supprimant le besoin d'une source de randomité forte, ou même de toute source de randomité, pendant la génération de signature.
La génération de clé privée, cependant, nécessite absolument une telle source fortement aléatoire. Dans les situations où (EC)DSA déterministe doit être utilisé en raison du manque d'une source appropriée de randomité, on doit supposer que la clé privée a été générée de manière externe et importée dans le système de génération de signature ou a été générée dans un contexte où la randomité était disponible. Par exemple, on peut imaginer une carte à puce qui génère sa clé privée alors qu'elle est encore en usine sous des conditions environnementales contrôlées, mais pour laquelle la génération de données aléatoires ne peut pas être garantie une fois déployée sur le terrain, lorsqu'elle est physiquement entre les mains d'attaquants potentiels.
La suppression de l'exigence de source aléatoire et la capacité de tester une implémentation par rapport à des vecteurs de test améliorent toutes deux la sécurité des implémentations de signataires DSA et ECDSA, en ce qu'elles aident à éviter des conditions d'échec difficiles à tester. Les schémas de signature déterministes peuvent également aider dans d'autres situations, par exemple pour éviter les duplicatas parasites, lorsque le même élément de données est signé plusieurs fois avec la même clé: avec un schéma de signature déterministe, la même signature est générée à chaque fois, rendant la détection de duplicatas beaucoup plus facile.
Inversement, le manque de randomisation peut avoir des effets néfastes dans certains protocoles avancés, par exemple liés à l'anonymat dans certains schémas de vote. En règle générale, DSA ou ECDSA déterministe peut être utilisé à la place du DSA ou ECDSA véritable, sans problèmes de sécurité supplémentaires, si le protocole global tolérerait un autre schéma de signature déterministe, en particulier RSA tel que spécifié dans PKCS #1 [RFC3447] (avec le rembourrage "type 1", pas PSS) ou ISO 9796-2 [ISO-9796-2]. La liste des protocoles dans lesquels DSA ou ECDSA déterministe est approprié inclut Transport Layer Security (TLS) [RFC5246], le Secure SHell (SSH) Protocol [RFC4251], Cryptographic Message Syntax (CMS) [RFC5652] et ses dérivés, les infrastructures de clés publiques X.509 [RFC5280], et bien d'autres.
La construction décrite dans ce document est connue sous le nom de "dérandomisation". Cela a été proposé pour divers schémas de signature. La sécurité repose sur le fait que la génération de k soit indiscernable de la sortie d'un oracle aléatoire. En gros, HMAC_DRBG est sécurisé dans ce rôle tant que HMAC se comporte comme une PRF (fonction pseudoaléatoire). Pour plus de détails sur la sécurité de HMAC et HMAC_DRBG, veuillez consulter [H2008] et [B2006]. Pour un traitement plus formel de la dérandomisation, voir [LN2009].
Un problème restant avec (EC)DSA déterministe, tel que présenté dans ce document, est la "double utilisation" de la clé privée x, à la fois comme clé privée dans l'algorithme de génération de signature lui-même et comme entrée à l'oracle pseudoaléatoire basé sur HMAC_DRBG pour produire la valeur k. Cela nécessite que HMAC_DRBG continue d'être un oracle aléatoire, même lorsque la clé publique (qui est calculée à partir de x) est également connue. Étant donné le manque de structure commune entre HMAC et les logarithmes discrets, cela semble être une hypothèse raisonnable.
Les attaques par canal auxiliaire sont une considération importante chaque fois qu'un attaquant peut mesurer avec précision des aspects d'une implémentation tels que la durée nécessaire pour effectuer une opération de signature ou la puissance consommée à chaque point d'une opération de signature. Le déterminisme des algorithmes décrits dans cette note peut être utile à un attaquant dans certaines formes d'attaques par canal auxiliaire, donc les implémentations DEVRAIENT utiliser des mesures défensives pour éviter de divulguer la clé privée par un canal auxiliaire.
5. Statut de la propriété intellectuelle
À notre connaissance, (EC)DSA déterministe n'est couvert par aucun brevet actif. Le document [BDLSY2011] pointe vers deux publications indépendantes de l'idée de dérandomisation par Barwood et Wigley, toutes deux au début de 1997, et également vers une demande de brevet par Naccache, M'Raihi et Levy-dit-Vehel quelques mois plus tard [NML1997], mais la demande a été retirée en 2003. Nous ne sommes au courant d'aucun autre brevet sur le sujet.
Annexe A. Exemples
A.1. Exemple détaillé
Nous détaillons ici les valeurs intermédiaires obtenues lors de la génération de k sur un exemple de message et de clé. Nous utilisons une courbe binaire car cette courbe spécifique est standard et a une longueur d'ordre de groupe (qlen) qui n'est pas un multiple de 8; cela illustre les détails fins de la façon dont les conversions sont effectuées entre les entiers et les séquences de bits.
A.1.1. Paire de clés
Nous considérons ECDSA sur la courbe K-163 décrite dans [FIPS-186-4] (également connue sous le nom "ansix9t163k1" dans [X9.62]). La courbe est définie sur un corps GF(2^163): les éléments de corps sont encodés en chaînes de 163 bits. L'ordre du point de base conventionnel est la valeur première:
q = 0x4000000000000000000020108A2E0CC0D99F8A5EF
qui a une longueur qlen = 163 bits.
Notre clé privée est:
x = 0x09A4D6792295A7F730FC3F2B49CBC0F62E862272F
La clé publique correspondante est le point de courbe U = xG. Ce point a deux coordonnées, qui sont des éléments du corps GF(2^163). Ces éléments peuvent être convertis en entiers en utilisant la procédure décrite dans la section A.5.6 de [X9.62], produisant les deux coordonnées de point public:
Ux = 0x79AEE090DB05EC252D5CB4452F356BE198A4FF96F
Uy = 0x782E29634DDC9A31EF40386E896BAA18B53AFA5A3
A.1.2. Génération de k
Dans cet exemple, nous utilisons la fonction de hachage SHA-256 [FIPS-180-4]. Le message d'entrée est l'encodage UTF-8 de la chaîne "sample" (6 octets, c'est-à-dire 48 bits).
Le message d'entrée haché h1 = SHA-256(m) est:
h1
AF 2B DB E1 AA 9B 6E C1 E2 AD E1 D6 94 F4 1F C7
1A 83 1D 02 68 E9 89 15 62 11 3D 8A 62 AD D1 BF
(32 octets; chaque valeur d'octet est listée en notation hexadécimale).
Nous convertissons la clé privée x en une séquence d'octets en utilisant la transformation int2octets:
int2octets(x)
00 9A 4D 67 92 29 5A 7F 73 0F C3 F2 B4 9C BC 0F
62 E8 62 27 2F
Note: Bien que la valeur spécifique de x tiendrait numériquement dans 160 bits, c'est-à-dire 20 octets, nous encodons toujours x en 21 octets, car la longueur d'encodage est déterminée par la longueur de q, qui est de 163 bits.
Nous tronquons et/ou étendons également le message haché en utilisant bits2octets:
bits2octets(h1)
01 79 5E DF 0D 54 DB 76 0F 15 6D 0D AC 04 C0 32
2B 3A 20 42 24
Les étapes b à g (voir la section 3.2) calculent ensuite les valeurs pour les variables K et V. Ces variables sont des séquences de 256 bits (la longueur de sortie de la fonction de hachage, arrondie au multiple suivant de 8). Nous reproduisons ici les valeurs successives:
V après l'étape b:
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
K après l'étape c:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
K après l'étape d:
09 99 9A 9B FE F9 72 D3 34 69 11 88 3F AD 79 51
D2 3F 2C 8B 47 F4 20 22 2D 11 71 EE EE AC 5A B8
V après l'étape e:
D5 F4 03 0F 75 5E E8 6A A1 0B BA 8C 09 DF 11 4F
F6 B6 11 1C 23 85 00 D1 3C 73 43 A8 C0 1B EC F7
K après l'étape f:
0C F2 FE 96 D5 61 9C 9E F5 3C B7 41 7D 49 D3 7E
A6 8A 4F FE D0 D7 E6 23 E3 86 89 28 99 11 BD 57
V après l'étape g:
78 34 57 C1 CF 31 48 A8 F2 A9 AE 73 ED 47 2F A9
8E D9 CD 92 5D 8E 96 4C E0 76 4D EF 3F 84 2B 9A
Dans l'étape h, nous effectuons la boucle finale. Puisque nous utilisons HMAC avec SHA-256, qui produit 256 bits de sortie, et nous n'avons besoin que de 163 bits pour T, une seule invocation HMAC produit le T suivant:
T (première tentative):
93 05 A4 6D E7 FF 8E B1 07 19 4D EB D3 FD 48 AA
20 D5 E7 65 6C BE 0E A6 9D 2A 8D 4E 7C 67 31 4A
qui, lorsqu'il est converti en un entier avec bits2int, donne un premier candidat pour k:
k1 = 0x4982D236F3FFC758838CA6F5E9FEA455106AF3B2B
Puisque cette valeur est supérieure à q-1, nous devons boucler. Cela implique d'abord de calculer de nouvelles valeurs pour K et V:
nouveau K:
75 CB 5C 05 B2 A7 8C 3D 81 DF 12 D7 4D 7B E0 A0
E9 4A B1 98 15 78 1D 4D 8E 29 02 A7 9D 0A 66 99
nouveau V:
DC B9 CA 12 61 07 A9 C2 7C E7 7B A5 8E A8 71 C8
C9 12 D8 35 EA DD C3 05 F2 44 5D 88 F6 6C 4C 43
puis un nouveau T:
T (deuxième tentative):
C7 0C 78 60 8A 3B 5B E9 28 9B E9 0E F6 E8 1A 9E
2C 15 16 D5 75 1D 2F 75 F5 00 33 E4 5F 73 BD EB
et un nouveau candidat pour k:
k2 = 0x63863C30451DADF4944DF4877B740D4F160A8B6AB
Puisque k2 est également supérieur à q-1, nous bouclons à nouveau:
nouveau K (2):
0A 5A 64 B9 9C 05 95 20 10 36 86 CB 6F 36 BC FC
A7 88 EB 3B CF 69 BA 66 A5 BB 08 0B 05 93 BA 53
nouveau V (2):
0B 3B 19 68 11 B1 9F 6C 6F 72 9C 43 F3 5B CF 0D
FD 72 5F 17 CA 34 30 E8 72 14 53 E5 55 50 A1 8F
T (troisième tentative):
47 5E 80 E9 92 14 05 67 FC C3 A5 0D AB 90 FE 84
BC D7 BB 03 63 8E 9C 46 56 A0 6F 37 F6 50 8A 7C
et nous obtenons finalement une valeur acceptable pour k:
k = 0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B
A.1.3. Signature
Avec notre clé privée et la valeur de k que nous venons de générer, nous pouvons maintenant calculer la signature en utilisant les mécanismes ECDSA standard. D'abord, le point kG est calculé, et la coordonnée X de ce point est convertie en un entier puis réduite modulo q, produisant la première moitié de signature:
r = 0x113A63990598A3828C407C0F4D2438D990DF99A7F
que nous utilisons, avec x (la clé privée), k (que nous avons calculé ci-dessus), et h = bits2int(h1), pour calculer la seconde moitié de signature:
s = 0x1313A2E03F5412DDB296A22E2C455335545672D9F
Une signature ECDSA est une paire d'entiers. Dans de nombreux protocoles qui nécessitent qu'une signature soit une séquence de bits (ou d'octets), il est d'usage d'encoder la signature comme une SEQUENCE ASN.1 de deux valeurs INTEGER, avec les règles DER. Cela résulte en la signature de 48 octets suivante:
30 2E 02 15 01 13 A6 39 90 59 8A 38 28 C4 07 C0
F4 D2 43 8D 99 0D F9 9A 7F 02 15 01 31 3A 2E 03
F5 41 2D DB 29 6A 22 E2 C4 55 33 55 45 67 2D 9F
A.2. Vecteurs de test
Dans les sections suivantes, nous donnons des vecteurs de test pour diverses tailles de clé et fonctions de hachage, à la fois pour DSA et ECDSA.
Tous les nombres sont donnés en notation hexadécimale. Chaque signature consiste en deux entiers, nommés r et s; de nombreuses implémentations encoderont ces entiers en une seule structure ASN.1 ou avec une autre convention d'encodage, ce qui est en dehors du cadre de ce document. Nous montrons également la valeur k utilisée en interne.
Pour chaque clé, nous listons dix signatures, correspondant à deux messages d'entrée distincts, et cinq des fonctions SHA [FIPS-180-4]: SHA-1, SHA-224, SHA-256, SHA-384 et SHA-512. Les deux messages d'entrée sont l'encodage UTF-8 des chaînes "sample" et "test" (sans les guillemets), de longueur 48 et 32 bits, respectivement.
Les exemples ECDSA utilisent les courbes standard décrites dans [FIPS-186-4].
A.3. Code exemple
Des exemples de code implémentant cette spécification sont disponibles sur le site Web de l'auteur.
A.1.2. Generation of k (Génération de k)
Dans cet exemple, nous utilisons la fonction de hachage SHA-256 [FIPS-180-4]. Le message d'entrée est l'encodage UTF-8 de la chaîne "sample" (6 octets, soit 48 bits).
Le message d'entrée haché h1 = SHA-256(m) est:
h1
AF 2B DB E1 AA 9B 6E C1 E2 AD E1 D6 94 F4 1F C7
1A 83 1D 02 68 E9 89 15 62 11 3D 8A 62 AD D1 BF
(32 octets; chaque valeur d'octet est listée en notation hexadécimale).
Nous convertissons la clé privée x en séquence d'octets en utilisant la transformation int2octets: Voir RFC 6979 Annexe A.1.2 pour les détails complets des valeurs intermédiaires.
Nous obtenons finalement une valeur acceptable pour k:
k = 0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B
A.2. Test Vectors (Vecteurs de test)
Dans les sous-sections suivantes, nous fournissons des vecteurs de test pour DSA et ECDSA avec diverses tailles de clé et fonctions de hachage.
Les vecteurs de test comprennent:
- A.2.1. à A.2.2.: DSA (1024 et 2048 bits)
- A.2.3. à A.2.7.: ECDSA sur corps premier (192, 224, 256, 384, 521 bits)
- A.2.8. à A.2.12.: ECDSA sur corps binaire, courbes de Koblitz (163, 233, 283, 409, 571 bits)
- A.2.13. à A.2.17.: ECDSA sur corps binaire, courbes pseudoaléatoires (163, 233, 283, 409, 571 bits)
Chaque vecteur de test contient:
- Paramètres de clé
- Clé privée et publique
- Signatures pour diverses fonctions de hachage (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512) pour les messages exemples "sample" et "test"
Ces vecteurs de test peuvent être utilisés pour vérifier la correction des implémentations (EC)DSA déterministes.
A.3. Sample Code (Code exemple)
Le document RFC 6979 original contient des références à du code d'implémentation exemple. Les implémenteurs devraient consulter:
- RFC 6979 Original pour les vecteurs de test complets
- Implémentation HMAC: RFC 2104
- Implémentation HMAC_DRBG: NIST SP 800-90A
Lors de l'implémentation, une attention particulière doit être portée à:
- L'implémentation correcte des conversions bits2int et bits2octets
- La garantie de calculs HMAC corrects
- La vérification que les valeurs k générées sont dans la plage valide
- L'utilisation des vecteurs de test fournis pour vérifier l'implémentation