Les briques · 5 min · démo interactive

La signature numérique : prouver sans révéler

Tu peux prouver que tu détiens une clé sans jamais la montrer. Une signature suffit, et tout le monde peut la vérifier avec ta seule clé publique.

L’idée en une phrase

Une signature numérique est un nombre, calculé à partir d'un message et d'une clé secrète, que n'importe qui peut vérifier sans connaître cette clé.

Elle prouve deux choses à la fois : le message vient du détenteur de la clé, et il n'a pas changé d'un seul bit depuis. Contrairement à une signature manuscrite, elle est différente pour chaque message. Copier la signature d'un message sur un autre ne fonctionne donc pas.

La démo

Mode éducatif Ne jamais utiliser pour de vrais fonds. Tout s’exécute dans ton navigateur, rien n’est envoyé ni conservé.

1. Le signataire

Clé publique

03089e339389b56ccb941bbccaef8515af7faed788267beab99b5556df1d36fe5f

Signature ECDSA (r et s, 64 octets)

r = 0efc8ed512bb3a94146ab0357a0654103892d0c8029ffecdd91bfb82090455ba s = 5cf135ffdd326377a37d9db544d7d30e4cb26dac65136dda76e11f4462d841f4

2. Le vérificateur

Il reçoit trois éléments, sans jamais voir la clé privée. Modifie-les ou utilise les boutons.

SHA-256 du message reçu

f1c85e344a4b062ad0f4499bb59f623ca79f03f06745d83532cad6004ff34333
Signature valide : ce message vient bien du détenteur de la clé, intact.

Sans JavaScript, voici un exemple réel. Pour le message « Alice paie 5 à Bob » et la clé de test affichée ci-dessus, le SHA-256 vaut f1c85e34…f34333 et la composante r de la signature commence par 0efc8ed5. Remplace le 5 par un 9 : le hash change entièrement, et le calcul de vérification n'aboutit plus à r.

Intégrer cette démo

Copie ce code sur ton site, ton cours ou ton blog. La démo reste gratuite ; garde simplement le lien vers protocole.org.

Pourquoi ça compte

Tu envoies une transaction à des milliers d'ordinateurs que tu ne connais pas. Aucun d'eux ne connaît ton nom, aucun n'a de mot de passe à vérifier. Si tu joignais ta clé privée en preuve, le premier nœud venu pourrait vider ton wallet.

La signature résout ce problème. Elle autorise exactement cette transaction, ce montant et ce destinataire. Un intermédiaire qui change le destinataire invalide tout. Il ne reste aucun secret à voler dans le message diffusé.

Le code

La démo en quelques lignes, avec la même bibliothèque. Change le texte de falsifie ou signe un autre message. Le code compare aussi ECDSA et Schnorr, les deux schémas présents dans Bitcoin.

Clique sur Lancer pour exécuter ce code dans ton navigateur.

Ce qui se passe vraiment

Dans la partie haute de la démo, le bouton Signer fait trois choses. Il calcule le hash du message, tire un nombre à usage unique k, puis produit les deux valeurs r et s. La valeur r est la coordonnée x du point k × G. La valeur s mélange le hash z, la clé privée d et k dans une seule égalité : s = (z + r·d) / k, modulo l'ordre de la courbe.

La partie basse rejoue ce que fait un nœud. À partir du hash, de r, de s et de la clé publique Q, il calcule le point (z/s) × G + (r/s) × Q. Si la signature est honnête, ce point tombe exactement sur k × G, et sa coordonnée x vaut r. Le vérificateur retrouve ainsi une valeur liée à k, sans connaître ni k ni d.

Les trois boutons d'altération attaquent chacun un maillon :

  • Altérer le message change le hash, donc z. Le point obtenu n'est plus le bon.
  • Changer un bit de la signature modifie r ou s. Là encore, l'égalité s'effondre, même pour un bit sur 512.
  • Prendre une autre clé publique remplace Q. Une signature n'est valable qu'avec la clé qui correspond au secret utilisé.

Signe deux fois de suite le même message avec la même clé : le résultat est identique. Ce n'est pas obligatoire en ECDSA, mais la bibliothèque applique la RFC 6979, qui déduit k du message et de la clé. Cette méthode élimine tout un type d'erreur, décrit plus bas.

Simplification assumée : la démo signe le SHA-256 d'un texte. Une vraie transaction Bitcoin signe un double SHA-256 de données structurées, et Ethereum un hash Keccak-256. Le mécanisme mathématique reste le même.

Dans la vraie vie

Chaque transaction Bitcoin ou Ethereum porte au moins une signature, et chaque nœud la vérifie. C'est ce qui rend inutile une autorité centrale : on n'a plus à savoir qui tu es, seulement à constater que le détenteur de la clé a bien autorisé la dépense.

Ethereum va plus loin : sa signature contient un petit indice de récupération, si bien que l'on peut recalculer la clé publique à partir de la signature, donc l'adresse de l'expéditeur. C'est pour cela qu'une transaction Ethereum n'a pas besoin d'indiquer qui l'envoie.

Depuis la mise à jour Taproot de novembre 2021, Bitcoin accepte aussi les signatures Schnorr, plus simples à analyser. Plusieurs signataires peuvent y combiner leurs clés pour produire une seule signature, indiscernable d'une signature ordinaire.

Hors blockchain, tu t'en sers en permanence : certificats HTTPS, mises à jour logicielles, code signé des systèmes d'exploitation. Le schéma varie, le principe est identique. La même signature autorise aussi les approbations de token, ce qui pose un autre problème : on peut signer valablement quelque chose de dangereux.

Ce qui peut mal tourner

  • Réutiliser le nonce k. Deux signatures avec le même k et des messages différents permettent de calculer la clé privée par une simple division. C'est ainsi que la clé de signature de la PlayStation 3 a été extraite, en 2010. En 2013, le défaut du générateur aléatoire d'Android a produit le même effet sur des wallets Bitcoin.
  • Signer sans lire. La mathématique garantit que tu as signé, pas que tu as compris. Le vol de Bybit a reposé sur des signataires légitimes trompés par ce qu'ils voyaient à l'écran.
  • Confondre signature et chiffrement. Une signature ne cache rien. Le message reste lisible par tous.
  • Accepter une clé publique de source douteuse. Une signature valide prouve seulement un lien avec cette clé. Si un attaquant t'a donné sa propre clé en prétendant être Bob, tout se vérifiera parfaitement.
  • Rejouer une signature. Une signature reste valide si le protocole n'y inclut pas un compteur ou un identifiant de chaîne. Ethereum ajoute un nonce de compte et, depuis EIP-155, l'identifiant de la chaîne.
  • Ignorer la malléabilité. Avec ECDSA, (r, s) et (r, n − s) sont tous deux valides. Bitcoin impose la forme à s bas et a écarté le problème des identifiants de transaction avec SegWit.

Teste-toi

1. Que faut-il pour vérifier une signature ?
2. Tu modifies une lettre du message signé. Que devient la signature ?
3. Pourquoi le nonce k d'ECDSA ne doit-il jamais servir deux fois ?