SM2 versleutelen / ontsleutelen / ondertekenen

De volledige SM2-publieke-sleutelgereedschapskist op de aanbevolen kromme sm2p256v1 (GB/T 32918.5): een sleutelpaar genereren, ondertekenen en verifiëren met het op SM3 gebaseerde ZA-schema (GB/T 32918.2), en coderen of decoderen in de standaardvolgorde C1C3C2, de verouderde volgorde C1C2C3, of ASN.1 DER. Alles draait in uw browser; er wordt niets geüpload.
Privésleutel (hex, 64 cijfers — behandel als een wachtwoord)
Publieke sleutel (hex, 130 cijfers met 04-voorvoegsel of 128 cijfers x||y)
De privésleutel wordt gebruikt door Ondertekenen en Decoderen; de publieke sleutel door Verifiëren en Coderen. Sleutels verlaten deze pagina nooit.
Gebruikers-ID(de "onderscheidende identificatie" die in ZA wordt gemengd; de standaard is de de-facto standaard)
Bericht lezen als: Vaste k (gevorderd):
r (hex)
s (hex)
Handtekening, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } - het formaat dat OpenSSL/GmSSL gebruiken)
Over het vaste-k-vak: elke echte handtekening moet een nieuwe, onvoorspelbare k gebruiken — hergebruik of raden van k lekt de privésleutel (de les van de Sony ECDSA-fout). Deze pagina genereert een willekeurige k uit crypto.getRandomValues wanneer het vak leeg is. Vul het vak alleen in om een bekende vector na te bootsen voor onderwijs of tests.
Gebruikers-ID(moet gelijk zijn aan die van de ondertekenaar)
Bericht lezen als: Handtekeningformaat:
r (hex)
s (hex)
✓ Handtekening is GELDIG
✗ Handtekening is ONGELDIG
Bericht lezen als: Cijfertekstformaat: Uitvoer:
Vaste k (gevorderd):
Herinnering hybride codering: SM2-codering is bedoeld voor korte geheimen (sessiesleutels, pincodes), niet voor grote hoeveelheden gegevens — elk bericht kost 96 bytes overhead voor C1+C3 en een vermenigvuldiging van een elliptische-krommepunt. Codeer een willekeurige SM4/AES-sleutel met SM2, en daarna de gegevens met de symmetrische cijfer (SM4-pagina / AES-pagina).
Cijfertekst lezen als: Orde: Klaartekst schrijven als:
OpenSSL-kruiscontrole — de C1C3C2-hex van deze pagina komt overeen met openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x met -pkeyopt ec_scheme:c1c3c2, de standaard), en de GmSSL-tooling gmssl sm2randkey / sm2encrypt; handtekeningen komen overeen met openssl dgst -sm3 -sign met dezelfde gebruikers-ID via -pkeyopt sm2_userid:1234567812345678. Een voorloopende 04-byte vóór C1 (zoals sommige bibliotheken maken) wordt bij decoderen geaccepteerd.
Naleving: SM2 is een algoritmekeuze die wordt gedreven door de Chinese regelgeving voor commerciële cryptografie en interoperabiliteit, met een beveiliging die vergelijkbaar is met 256-bits ECC (NIST P-256). Combineer het in productie met een echt sleutelbeheersysteem of hardwaresleutels — een browserpagina is een rekenmachine, geen kluis.
Zelftest
Speelt de sleutelafleidings-, vaste-k-handtekenings- en coderingsvectoren af die zijn gemaakt door een onafhankelijke Python-referentie-implementatie (en gecontroleerd met gmssl), de DER-handtekening- en DER-cijferteksrondes, willekeurige-k ondertekenen/verifiëren en coderen/decoderen-rondes, en de negatieve paden (gemanipuleerde C3, afgekapte cijfertekst, publieke sleutel buiten de kromme, r = 0).
Wat is SM2?
In één zin: SM2 is het Chinese nationale standaard publieke-sleutelcryptosysteem — een elliptische-kromme-handtekening- en coderingsschema over de vaste kromme sm2p256v1, gepubliceerd als GB/T 32918-2016 (eerder GM/T 0003-2012), en vervult in de Chinese "SM"-suite de rol die ECDSA/ECDH (P-256) in de NIST-wereld spelen.
ECC in één alinea (de intuïtie)

Alle cryptografie met elliptische krommen rust op één truc: gegeven het basispunt G op een kromme over een groot priemveld en het veelvoud P = d·G, is het berekenen van d uit P het oplossen van het discrete-logaritmeprobleem van de elliptische kromme, waarvoor geen snel algoritme bekend is. De privésleutel d is slechts een getal van 256 bits; de publieke sleutel is het punt d·G. SM2 is geen nieuwe krommerekenkunde — het is een specifieke manier om te ondertekenen (zoals ECDSA) en te coderen (zoals een miniatuur-ECIES) op één specifieke kromme, met SM3 in plaats van SHA voor de hash.

sm2p256v1 versus NIST P-256
Kenmerksm2p256v1NIST P-256 (secp256r1)
Veldgrootte256-bits priemgetal256-bits priemgetal
Krommevormy² = x³ + ax + by² = x³ − 3x + b (a = −3)
Beveiligingsniveau≈ 128 bits≈ 128 bits
HandtekeningSM2 (GB/T 32918.2), op SM3 gebaseerd, gebruikers-ID gebonden in ZAECDSA met SHA-256
CoderingSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, niet door NIST gestandaardiseerd)
HashSM3 (GB/T 32905)SHA-2-familie
Gepubliceerdontwerp uit 2010, GM/T 0003-2012, GB/T 32918-2016; in ISO/IEC 14888-31999 (SEC 2 / NIST)
TLS-ondersteuningTLCP (GM/T 386) en TLS 1.3-suites volgens RFC 8998overal

Beide krommen bieden dezelfde concrete beveiliging; geen van beide heeft een praktische aanval. De keuze tussen beide is regelgevend en gaat over interoperabiliteit, niet over sterkte.

De gebruikers-ID en ZA — wat SM2 ondertekent dat ECDSA niet doet

Vóór het hashen verwerkt SM2 de identiteit van de ondertekenaar in de digest: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), waarbij ENTLa de bitlengte van de ID is, de middelste vier velden de exacte kromme vastleggen, en de laatste twee de publieke sleutel van de ondertekenaar zijn. Het bericht wordt gehasht als SM3(ZA ‖ M). Twee gevolgen: een handtekening is gebonden aan de opgegeven identiteit (een voordeel), en de verifier moet de ID van de ondertekenaar kennen en dezelfde gebruiken (een klassieke interoperabiliteitsval). Bijna het hele ecosysteem is uitgekomen op de standaard-ID van 16 cijfers 1234567812345678 — niet uit de standaardtekst, maar uit de voorbeelden in de bijlage van GM/T 0003; de standaard van OpenSSL komt daarmee overeen, en deze pagina ook.

Cijferteksformaten: C1C3C2, C1C2C3 en DER

Een SM2-cijfertekst bestaat uit drie delen: C1 = het vluchtige punt kG (64 bytes, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 bytes, integriteit), C2 = M ⊕ KDF(x2 ‖ y2) (het gemaskeerde bericht). De tekst uit 2012 (GM/T 0003) plakte ze achter elkaar als C1 ‖ C2 ‖ C3; de standaard uit 2016 (GB/T 32918.4) zette ze om naar C1 ‖ C3 ‖ C2, en OpenSSL 1.1.1+ volgde. Oude bank- en overheidssystemen spreken nog steeds de oude volgorde — daarom heeft deze pagina beide, plus de ASN.1-vorm (SEQUENCE van INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2) die sommige bibliotheken uitgeven. Wanneer decoderen met de tool van de andere partij mislukt, is de bytevolgorde het eerste dat u moet controleren.

Veelgemaakte fouten
  • k hergebruiken of er zuinig mee zijn. De nonce k moet bij zowel ondertekenen als coderen per bewerking nieuw en onvoorspelbaar zijn. Eén herhaalde k over twee handtekeningen geeft de privésleutel aan iedereen die beide ziet. Deze pagina trekt k uit de CSPRNG van de browser; de vaste-k-vakken bestaan alleen om bekende vectoren na te bootsen.
  • Niet-overeenkomende gebruikers-ID's. Ondertekenen met de standaard-ID en verifiëren met een eigen ID (of andersom) laat elke geldige handtekening mislukken. De ID maakt deel uit van de ondertekende gegevens.
  • Overal C1C3C2 aannemen. Systemen uit de GM/T 0003-tijd, sommige smartcards en oudere GmSSL-builds gebruiken standaard C1C2C3; diverse tools voegen ook een niet-gecomprimeerde punt-byte 04 toe. Deze pagina accepteert al deze vormen bij decoderen.
  • Grote hoeveelheden gegevens met SM2 coderen. Elke cijfertekst draagt 96 bytes overhead en kost twee puntvermenigvuldigingen. Gebruik SM2 voor een sleutel, SM4/AES voor de gegevens.
  • Een publieke sleutel met 04-voorvoegsel behandelen als 65 ruwe bytes sleutel. De 04 is een coderingsmarkering: de sleutel zelf is x ‖ y, 128 hexadecimale cijfers. Deze pagina accepteert beide schrijfwijzen.
Veelgestelde vragen

Is dit compatibel met OpenSSL / GmSSL? Ja. De C1C3C2-hex-uitvoer komt overeen met openssl pkeyutl -sm2encrypt voor dezelfde publieke sleutel, bericht en k; DER-handtekeningen komen byte voor byte overeen met de uitvoer van openssl dgst -sm3 -sign (stel de gebruikers-ID in met -pkeyopt sm2_userid:...). Runs met willekeurige k verschillen natuurlijk — vergelijk door te decoderen/verifiëren, niet door gelijkheid.

Waarom is er hier geen SM2-sleuteluitwisseling? GB/T 32918.3 definieert een interactief geauthenticeerd sleuteluitwisselingsprotocol; het heeft geen zin als rekenmachine van één pagina. Ondertekenen en coderen dekken de niet-interactieve toepassingen.

Zit SM2 in WebCrypto? Nee — geen enkele browser implementeert het (Chrome levert het alleen achter niet-standaard vlaggen, als al). Deze pagina draait een vanaf nul geschreven JavaScript-implementatie, met de eigen bijlagevectoren van de standaard bedraad in de zelftest hierboven.

Kan ik een PEM-sleutel van OpenSSL gebruiken? Exporteer in plaats daarvan de ruwe hex: openssl ec -in key.pem -text drukt de private scalar en het publieke punt af. Deze pagina accepteert alleen hex-sleutels, bewust — de PEM/SEC1-machinerie hoort op de RSA-pagina thuis.

Wat is dan SM9? Een ander beest: identiteitsgebaseerde cryptografie, waarin elke tekenreeks (een e-mailadres) de publieke sleutel is en een KGC privésleutels uitgeeft. Zie de SM9-overzichtspagina.