Chiffrement / déchiffrement / signature SM2

La boîte à outils complète de clé publique SM2 sur la courbe recommandée sm2p256v1 (GB/T 32918.5) : générez une paire de clés, signez et vérifiez avec le schéma ZA fondé sur SM3 (GB/T 32918.2), et chiffrez ou déchiffrez selon l’ordre standard C1C3C2, l’ordre hérité C1C2C3, ou ASN.1 DER. Tout s’exécute dans votre navigateur ; rien n’est envoyé.
Clé privée (hexadécimal, 64 chiffres — à traiter comme un mot de passe)
Clé publique (hexadécimal, 130 chiffres avec le préfixe 04, ou 128 chiffres x||y)
La clé privée sert à Signer et à Déchiffrer ; la clé publique à Vérifier et à Chiffrer. Les clés ne quittent jamais cette page.
Identifiant d’utilisateur(l’« identifiant distinctif » intégré à ZA ; la valeur par défaut est le standard de fait)
Lire le message comme : k fixe (avancé) :
r (hexadécimal)
s (hexadécimal)
Signature, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } — le format qu’utilisent OpenSSL/GmSSL)
À propos de la case k fixe : chaque signature réelle doit utiliser un k neuf et imprévisible — réutiliser ou deviner k divulgue la clé privée (la leçon de l’ECDSA de Sony). Cette page génère un k aléatoire à partir de crypto.getRandomValues dès que la case est vide. Ne remplissez la case que pour reproduire un vecteur connu, à des fins pédagogiques ou de test.
Identifiant d’utilisateur(doit correspondre à celui du signataire)
Lire le message comme : Format de la signature :
r (hexadécimal)
s (hexadécimal)
✓ Signature VALIDE
✗ Signature INVALIDE
Lire le message comme : Format du chiffré : Sortie :
k fixe (avancé) :
Rappel sur le chiffrement hybride : le chiffrement SM2 est destiné à de courts secrets (clés de session, codes PIN), non aux données volumineuses — chaque message supporte 96 octets de surcharge C1+C3 et une multiplication de point sur courbe elliptique. Chiffrez une clé SM4/AES aléatoire avec SM2, puis les données avec le chiffrement symétrique (page SM4 / page AES).
Lire le chiffré comme : Ordre : Écrire le texte clair comme :
Vérification croisée OpenSSL : le hexadécimal C1C3C2 de cette page correspond à openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x avec -pkeyopt ec_scheme:c1c3c2, par défaut), et aux outils GmSSL gmssl sm2randkey / sm2encrypt ; les signatures correspondent à openssl dgst -sm3 -sign avec le même identifiant d’utilisateur via -pkeyopt sm2_userid:1234567812345678. Un octet 04 en tête avant C1 (comme le produisent plusieurs bibliothèques) est accepté au déchiffrement.
Note de conformité : SM2 est un choix d’algorithme dicté par la conformité et l’interopérabilité de la cryptographie commerciale chinoise, avec une sécurité comparable à l’ECC de 256 bits (NIST P-256). En production, associez-le à un véritable système de gestion de clés ou à des clés matérielles — une page de navigateur est une calculatrice, pas un coffre.
Autotest
Rejoue les vecteurs de dérivation de clés, de signature à k fixe et de chiffrement produits par une implémentation de référence Python indépendante (et recoupés avec gmssl), les allers-retours de signature DER et de chiffré DER, les allers-retours signature/vérification et chiffrement/déchiffrement à k aléatoire, et les cas négatifs (C3 altéré, chiffré tronqué, clé publique hors courbe, r = 0).
Qu’est-ce que SM2 ?
En une phrase : SM2 est le cryptosystème à clé publique de la norme nationale chinoise — un schéma de signature et de chiffrement sur courbe elliptique, sur la courbe fixe sm2p256v1, publié sous la référence GB/T 32918-2016 (auparavant GM/T 0003-2012), et jouant dans la suite chinoise « SM » le rôle qu’ECDSA/ECDH (P-256) jouent dans le monde NIST.
L’ECC en un paragraphe (l’intuition)

Toute la cryptographie sur courbe elliptique repose sur une astuce : étant donnés le point de base G sur une courbe définie sur un grand corps premier et le multiple P = d·G, calculer d à partir de P revient à résoudre le problème du logarithme discret sur courbe elliptique, pour lequel aucun algorithme rapide n’est connu. La clé privée d n’est qu’un nombre de 256 bits ; la clé publique est le point d·G. SM2 n’est pas une nouvelle arithmétique de courbe — c’est une manière précise de signer (comme ECDSA) et de chiffrer (comme un ECIES miniature) sur une courbe donnée, avec un hachage SM3 au lieu de SHA.

sm2p256v1 contre NIST P-256
Aspectsm2p256v1NIST P-256 (secp256r1)
Taille du corpspremier de 256 bitspremier de 256 bits
Forme de la courbey² = x³ + ax + by² = x³ − 3x + b (a = −3)
Niveau de sécurité≈ 128 bits≈ 128 bits
SignatureSM2 (GB/T 32918.2), fondé sur SM3, identifiant d’utilisateur lié à ZAECDSA avec SHA-256
ChiffrementSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, non normalisé par le NIST)
HachageSM3 (GB/T 32905)Famille SHA-2
Publicationconception 2010, GM/T 0003-2012, GB/T 32918-2016 ; dans ISO/IEC 14888-31999 (SEC 2 / NIST)
Prise en charge TLSTLCP (GM/T 386) et suites TLS 1.3 de la RFC 8998partout

Les deux courbes offrent la même sécurité concrète ; aucune n’a d’attaque pratique. Le choix entre elles relève de la réglementation et de l’interopérabilité, non de la robustesse.

L’identifiant d’utilisateur et ZA — ce que SM2 signe et qu’ECDSA ne signe pas

Avant de hacher, SM2 intègre l’identité du signataire à l’empreinte : ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), où ENTLa est la longueur en bits de l’ID, les quatre champs du milieu fixent la courbe exacte, et les deux derniers sont la clé publique du signataire. Le message est haché comme SM3(ZA ‖ M). Deux conséquences : une signature est liée à l’identité revendiquée (un atout), et le vérificateur doit connaître l’ID du signataire et utiliser le même (un piège classique d’interopérabilité). Presque tout l’écosystème s’est fixé sur l’identifiant par défaut à 16 chiffres 1234567812345678 — non pas dans le texte de la norme, mais dans les exemples de l’annexe de GM/T 0003 ; l’OpenSSL par défaut le reprend, et cette page aussi.

Formats de chiffré : C1C3C2, C1C2C3 et DER

Un chiffré SM2 comporte trois parties : C1 = le point éphémère kG (64 octets, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 octets, intégrité), C2 = M ⊕ KDF(x2 ‖ y2) (le message masqué). Le texte GM/T 0003 de 2012 les concaténait C1 ‖ C2 ‖ C3 ; la norme GB/T 32918.4 de 2016 les a réordonnés en C1 ‖ C3 ‖ C2, et OpenSSL 1.1.1+ l’a suivie. Les anciens systèmes bancaires et administratifs parlent encore l’ancien ordre — c’est pourquoi cette page propose les deux, ainsi que la forme ASN.1 (SEQUENCE de INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2) que certaines bibliothèques produisent. Lorsque le déchiffrement échoue avec l’outil de l’autre partie, l’ordre des octets est la première chose à vérifier.

Erreurs courantes
  • Réutiliser ou bâcler k. Le nonce k, en signature comme en chiffrement, doit être neuf et imprévisible à chaque opération. Un même k répété dans deux signatures livre la clé privée à quiconque voit les deux. Cette page tire k du CSPRNG du navigateur ; les cases de k fixe ne servent qu’à reproduire des vecteurs connus.
  • Identifiants d’utilisateur différents. Signez avec l’identifiant par défaut, vérifiez avec un identifiant personnalisé (ou l’inverse), et chaque signature valide échoue. L’identifiant fait partie des données signées.
  • Supposer que C1C3C2 est partout. Les systèmes de l’ère GM/T 0003, certaines cartes à puce et les anciennes versions de GmSSL utilisent par défaut C1C2C3 ; plusieurs outils ajoutent aussi un octet 04 de point non compressé. Cette page accepte toutes ces variantes au déchiffrement.
  • Chiffrer des données volumineuses avec SM2. Chaque chiffré porte 96 octets de surcharge et coûte deux multiplications de points. Utilisez SM2 sur une clé, SM4/AES sur les données.
  • Prendre une clé publique préfixée par 04 pour 65 octets bruts de clé. Le 04 est un marqueur d’encodage : la clé elle-même est x ‖ y, soit 128 chiffres hexadécimaux. Cette page accepte les deux écritures.
FAQ

Est-ce compatible avec OpenSSL / GmSSL ? Oui. La sortie hexadécimale C1C3C2 correspond à openssl pkeyutl -sm2encrypt pour la même clé publique, le même message et le même k ; les signatures DER correspondent octet pour octet à la sortie de openssl dgst -sm3 -sign (définissez l’identifiant d’utilisateur avec -pkeyopt sm2_userid:...). Les exécutions à k aléatoire diffèrent bien sûr — comparez en déchiffrant ou en vérifiant, non par égalité.

Pourquoi n’y a-t-il pas d’échange de clés SM2 ici ? GB/T 32918.3 définit un protocole interactif d’échange de clés authentifié ; il n’a aucun sens comme calculatrice d’une seule page. La signature et le chiffrement couvrent les usages non interactifs.

SM2 est-il dans WebCrypto ? Non — aucun navigateur ne l’implémente (Chrome ne le fournit que derrière des drapeaux non standard, le cas échéant). Cette page exécute une implémentation JavaScript écrite de zéro, avec les vecteurs d’annexe de la norme branchés sur l’autotest ci-dessus.

Puis-je utiliser une clé PEM d’OpenSSL ? Exportez plutôt l’hexadécimal brut : openssl ec -in key.pem -text affiche le scalaire privé et le point public. Cette page n’accepte que des clés hexadécimales, volontairement — la mécanique PEM/SEC1 relève de la page RSA, où elle a sa place.

Qu’est-ce que SM9 alors ? Une tout autre bête : la cryptographie basée sur l’identité, où n’importe quelle chaîne (une adresse e-mail) est la clé publique et où un KGC délivre les clés privées. Voir la page de présentation de SM9.