SM2 verschlüsseln / entschlüsseln / signieren

Die vollständige SM2-Werkzeugkiste für öffentliche Schlüssel auf der empfohlenen Kurve sm2p256v1 (GB/T 32918.5): ein Schlüsselpaar erzeugen, mit dem SM3-basierten ZA-Verfahren (GB/T 32918.2) signieren und prüfen sowie in der Standardreihenfolge C1C3C2, der älteren Reihenfolge C1C2C3 oder als ASN.1 DER verschlüsseln und entschlüsseln. Alles läuft in Ihrem Browser; nichts wird hochgeladen.
Privater Schlüssel (Hex, 64 Ziffern — wie ein Passwort behandeln)
Öffentlicher Schlüssel (Hex, 130 Ziffern mit Präfix 04 oder 128 Ziffern x||y)
Der private Schlüssel wird von Signieren und Entschlüsseln verwendet, der öffentliche von Prüfen und Verschlüsseln. Schlüssel verlassen diese Seite nie.
Benutzer-ID(die "unterscheidende Kennung", die in ZA gemischt wird; Standard ist der de-facto-Standard)
Nachricht lesen als: Festes k (erweitert):
r (Hex)
s (Hex)
Signatur, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } – das Format, das OpenSSL/GmSSL verwenden)
Zum Feld für das feste k: Jede echte Signatur muss ein neues, unvorhersagbares k verwenden — die Wiederverwendung oder das Erraten von k legt den privaten Schlüssel offen (die Lehre aus dem ECDSA-Vorfall bei Sony). Diese Seite erzeugt ein zufälliges k über crypto.getRandomValues, wann immer das Feld leer ist. Füllen Sie das Feld nur aus, um einen bekannten Testvektor zu Lehr- oder Testzwecken nachzubilden.
Benutzer-ID(muss mit der des Signierenden übereinstimmen)
Nachricht lesen als: Signaturformat:
r (Hex)
s (Hex)
✓ Signatur ist GÜLTIG
✗ Signatur ist UNGÜLTIG
Nachricht lesen als: Chiffretext-Format: Ausgabe:
Festes k (erweitert):
Erinnerung zur hybriden Verschlüsselung: Die SM2-Verschlüsselung ist für kurze Geheimnisse gedacht (Sitzungsschlüssel, PINs), nicht für Massendaten — jede Nachricht trägt 96 Byte Overhead für C1+C3 und eine Multiplikation auf der elliptischen Kurve. Verschlüsseln Sie einen zufälligen SM4-/AES-Schlüssel mit SM2 und die Daten dann mit dem symmetrischen Verfahren (SM4-Seite / AES-Seite).
Chiffretext lesen als: Reihenfolge: Klartext schreiben als:
Kreuzprüfung mit OpenSSL — die C1C3C2-Hex-Ausgabe dieser Seite stimmt mit openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem überein (OpenSSL 3.x mit -pkeyopt ec_scheme:c1c3c2, dem Standard), und mit den Werkzeugen von GmSSL gmssl sm2randkey / sm2encrypt; Signaturen stimmen mit openssl dgst -sm3 -sign überein, wenn dieselbe Benutzer-ID über -pkeyopt sm2_userid:1234567812345678 gesetzt ist. Ein führendes Byte 04 vor C1 (wie es mehrere Bibliotheken erzeugen) wird beim Entschlüsseln akzeptiert.
Hinweis zur Konformität: SM2 ist eine Algorithmuswahl, die sich aus der chinesischen Konformität bei kommerzieller Kryptografie und der Interoperabilität ergibt; die Sicherheit ist mit 256-Bit-ECC (NIST P-256) vergleichbar. In der Produktion sollten Sie es mit einem echten Schlüsselverwaltungssystem oder Hardware-Schlüsseln kombinieren — eine Browserseite ist ein Rechner, kein Tresor.
Selbsttest
Spielt die Schlüsselableitung, die Signaturen mit festem k und die Verschlüsselungsvektoren ab, die eine unabhängige Referenzimplementierung in Python erzeugt hat (und mit gmssl gegengeprüft wurden), die Hin- und Rückumwandlungen von DER-Signaturen und DER-Chiffretexten, das Signieren/Prüfen und Verschlüsseln/Entschlüsseln mit zufälligem k sowie die Negativpfade (manipuliertes C3, abgeschnittener Chiffretext, öffentlicher Schlüssel nicht auf der Kurve, r = 0).
Was ist SM2?
In einem Satz: SM2 ist das chinesische nationale Standard-Public-Key-Kryptosystem — ein Signatur- und Verschlüsselungsverfahren auf elliptischen Kurven über der festen Kurve sm2p256v1, veröffentlicht als GB/T 32918-2016 (zuvor GM/T 0003-2012). Es übernimmt im chinesischen „SM“-Paket die Rolle, die ECDSA/ECDH (P-256) in der NIST-Welt spielen.
ECC in einem Absatz (die Anschauung)

Alle Kryptografie auf elliptischen Kurven beruht auf einem Trick: Gegeben der Basispunkt G auf einer Kurve über einem großen Primkörper und das Vielfache P = d·G, bedeutet die Berechnung von d aus P, das Problem des diskreten Logarithmus auf elliptischen Kurven zu lösen, für das kein schneller Algorithmus bekannt ist. Der private Schlüssel d ist nur eine 256-Bit-Zahl; der öffentliche Schlüssel ist der Punkt d·G. SM2 ist keine neue Kurvenarithmetik — es ist eine bestimmte Art zu signieren (wie ECDSA) und zu verschlüsseln (wie ein kleines ECIES) auf einer bestimmten Kurve, wobei mit SM3 statt SHA gehasht wird.

sm2p256v1 gegenüber NIST P-256
Aspektsm2p256v1NIST P-256 (secp256r1)
Körpergröße256-Bit-Primzahl256-Bit-Primzahl
Kurvenformy² = x³ + ax + by² = x³ − 3x + b (a = −3)
Sicherheitsniveau≈ 128 Bit≈ 128 Bit
SignaturSM2 (GB/T 32918.2), SM3-basiert, Benutzer-ID in ZA gebundenECDSA mit SHA-256
VerschlüsselungSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, nicht NIST-standardisiert)
HashSM3 (GB/T 32905)SHA-2-Familie
VeröffentlichtEntwurf 2010, GM/T 0003-2012, GB/T 32918-2016; in ISO/IEC 14888-31999 (SEC 2 / NIST)
TLS-UnterstützungTLCP (GM/T 386) und TLS-1.3-Suiten nach RFC 8998überall

Beide Kurven bieten dieselbe konkrete Sicherheit; keine hat einen praktischen Angriff. Die Wahl zwischen ihnen ist eine Frage der Regulierung und Interoperabilität, nicht der Stärke.

Die Benutzer-ID und ZA — was SM2 signiert, was ECDSA nicht tut

Vor dem Hashen fasst SM2 die Identität des Signierenden in den Digest ein: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), wobei ENTLa die Bitlänge der ID ist, die mittleren vier Felder die genaue Kurve festlegen und die letzten beiden der öffentliche Schlüssel des Signierenden sind. Die Nachricht wird als SM3(ZA ‖ M) gehasht. Zwei Folgen: Eine Signatur ist an die behauptete Identität gebunden (ein Merkmal), und der Prüfer muss die ID des Signierenden kennen und dieselbe verwenden (eine klassische Falle bei der Interoperabilität). Nahezu das gesamte Ökosystem hat sich auf die 16-stellige Standard-ID 1234567812345678 geeinigt — nicht aus dem Standardtext, sondern aus den Anhangsbeispielen von GM/T 0003; das Standardverhalten von OpenSSL stimmt damit überein, und diese Seite ebenso.

Chiffretext-Formate: C1C3C2, C1C2C3 und DER

Ein SM2-Chiffretext hat drei Teile: C1 = der flüchtige Punkt kG (64 Byte, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 Byte, Integrität), C2 = M ⊕ KDF(x2 ‖ y2) (die maskierte Nachricht). Der Text von GM/T 0003 aus dem Jahr 2012 verkettete sie als C1 ‖ C2 ‖ C3; der Standard GB/T 32918.4 aus dem Jahr 2016 ordnete auf C1 ‖ C3 ‖ C2 um, und OpenSSL 1.1.1+ folgte. Alte Bank- und Behördensysteme sprechen noch die alte Reihenfolge — deshalb hat diese Seite beide, dazu die ASN.1-Form (SEQUENCE aus INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2), die manche Bibliotheken ausgeben. Wenn das Entschlüsseln mit dem Werkzeug der Gegenseite fehlschlägt, ist die Byte-Reihenfolge das Erste, was Sie prüfen sollten.

Häufige Fehler
  • k wiederverwenden oder bei k sparen. Das Nonce k muss beim Signieren und Verschlüsseln bei jedem Vorgang neu und unvorhersagbar sein. Ein einziges wiederholtes k über zwei Signaturen gibt den privaten Schlüssel jedem preis, der beide sieht. Diese Seite zieht k aus dem CSPRNG des Browsers; die Felder für festes k existieren nur, um bekannte Vektoren nachzubilden.
  • Abweichende Benutzer-IDs. Signieren Sie mit der Standard-ID und prüfen Sie mit einer eigenen (oder umgekehrt), und jede gültige Signatur schlägt fehl. Die ID ist Teil der signierten Daten.
  • Überall C1C3C2 voraussetzen. Systeme aus der Zeit von GM/T 0003, manche Smartcards und ältere GmSSL-Builds verwenden standardmäßig C1C2C3; mehrere Werkzeuge stellen außerdem ein unkomprimiertes Punkt-Byte 04 voran. Diese Seite akzeptiert all diese Formen beim Entschlüsseln.
  • Massendaten mit SM2 verschlüsseln. Jeder Chiffretext trägt 96 Byte Overhead und kostet zwei Punktmultiplikationen. Verwenden Sie SM2 für einen Schlüssel, SM4/AES für die Daten.
  • Einen öffentlichen Schlüssel mit Präfix 04 als 65 rohe Schlüsselbytes behandeln. Die 04 ist eine Kodierungsmarkierung: Der Schlüssel selbst ist x ‖ y, 128 Hex-Ziffern. Diese Seite akzeptiert beide Schreibweisen.
FAQ

Ist das mit OpenSSL / GmSSL kompatibel? Ja. Die C1C3C2-Hex-Ausgabe stimmt mit openssl pkeyutl -sm2encrypt für denselben öffentlichen Schlüssel, dieselbe Nachricht und dasselbe k überein; DER-Signaturen stimmen Byte für Byte mit der Ausgabe von openssl dgst -sm3 -sign überein (setzen Sie die Benutzer-ID mit -pkeyopt sm2_userid:...). Läufe mit zufälligem k unterscheiden sich natürlich — vergleichen Sie durch Entschlüsseln bzw. Prüfen, nicht durch Gleichheit.

Warum gibt es hier keinen SM2-Schlüsselaustausch? GB/T 32918.3 definiert ein interaktives, authentifiziertes Schlüsselaustauschprotokoll; als Ein-Seiten-Rechner ergibt es keinen Sinn. Signieren und Verschlüsseln decken die nicht interaktiven Verwendungen ab.

Ist SM2 in WebCrypto enthalten? Nein — kein Browser implementiert es (Chrome liefert es nur hinter nicht standardisierten Flags, wenn überhaupt). Diese Seite nutzt eine von Grund auf neu geschriebene JavaScript-Implementierung, deren Anhangsvektoren des Standards im oben genannten Selbsttest eingebunden sind.

Kann ich einen PEM-Schlüssel aus OpenSSL verwenden? Exportieren Sie stattdessen das rohe Hex: openssl ec -in key.pem -text gibt den privaten Skalar und den öffentlichen Punkt aus. Diese Seite nimmt absichtlich nur Hex-Schlüssel an — die PEM/SEC1-Mechanik gehört auf die RSA-Seite, wo sie hingehört.

Was ist dann SM9? Ein anderes Tier: identitätsbasierte Kryptografie, bei der jede Zeichenkette (eine E-Mail-Adresse) der öffentliche Schlüssel ist und eine KGC private Schlüssel ausstellt. Siehe die Übersichtsseite zu SM9.