SM2 Cifra / Decifra / Firma

L'intero set di strumenti a chiave pubblica SM2 sulla curva raccomandata sm2p256v1 (GB/T 32918.5): generi una coppia di chiavi, firmi e verifichi con lo schema ZA basato su SM3 (GB/T 32918.2), e cifri o decifri nell'ordine standard C1C3C2, nell'ordine legacy C1C2C3, oppure in ASN.1 DER. Tutto funziona nel suo browser; nulla viene caricato.
Chiave privata (esadecimale, 64 cifre — trattela come una password)
Chiave pubblica (esadecimale, 130 cifre con prefisso 04 oppure 128 cifre x||y)
La chiave privata è usata da Firma e Decifra; la chiave pubblica da Verifica e Cifra. Le chiavi non lasciano mai questa pagina.
ID utente(l'«identificatore distintivo» mescolato in ZA; il predefinito è lo standard di fatto)
Leggi il messaggio come: k fisso (avanzato):
r (esadecimale)
s (esadecimale)
Firma, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } — il formato usato da OpenSSL/GmSSL)
Sul campo del k fisso: ogni firma reale deve usare un k nuovo e imprevedibile — riusare o indovinare k divulga la chiave privata (la lezione dell'ECDSA di Sony). Questa pagina genera un k casuale da crypto.getRandomValues ogni volta che il campo è vuoto. Riempia il campo solo per riprodurre un vettore noto a scopo didattico o di test.
ID utente(deve corrispondere a quello del firmatario)
Leggi il messaggio come: Formato della firma:
r (esadecimale)
s (esadecimale)
✓ La firma è VALIDA
✗ La firma NON è valida
Leggi il messaggio come: Formato del ciphertext: Output:
k fisso (avanzato):
Promemoria sulla cifratura ibrida: la cifratura SM2 è pensata per segreti brevi (chiavi di sessione, PIN), non per dati di grandi dimensioni — ogni messaggio paga 96 byte di sovraccarico C1+C3 e una moltiplicazione di punti su curva ellittica. Cifri una chiave SM4/AES casuale con SM2, poi i dati con il cifrario simmetrico (pagina SM4 / pagina AES).
Leggi il ciphertext come: Ordine: Scrivi il testo in chiaro come:
Verifica incrociata con OpenSSL — l'esadecimale C1C3C2 di questa pagina corrisponde a openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x con -pkeyopt ec_scheme:c1c3c2, il predefinito), e agli strumenti GmSSL gmssl sm2randkey / sm2encrypt; le firme corrispondono a openssl dgst -sm3 -sign con lo stesso ID utente tramite -pkeyopt sm2_userid:1234567812345678. Un byte 04 prima di C1 (come producono diverse librerie) viene accettato in decifratura.
Nota sulla conformità: SM2 è una scelta algoritmica imposta dalla conformità e dall'interoperabilità della crittografia commerciale cinese, con una sicurezza paragonabile all'ECC a 256 bit (NIST P-256). In produzione abbinatela a un vero sistema di gestione delle chiavi o a chiavi hardware — una pagina del browser è una calcolatrice, non una cassaforte.
Autotest
Riproduce i vettori di derivazione delle chiavi, di firma con k fisso e di cifratura prodotti da un'implementazione di riferimento Python indipendente (e verificati con gmssl), le andate e ritorni di firma e ciphertext DER, le andate e ritorni firma/verifica e cifratura/decifratura con k casuale, e i percorsi negativi (C3 alterato, ciphertext troncato, chiave pubblica fuori dalla curva, r = 0).
Che cos'è SM2?
In una frase: SM2 è il sistema crittografico a chiave pubblica dello standard nazionale cinese — uno schema di firma e cifratura a curve ellittiche sulla curva fissa sm2p256v1, pubblicato come GB/T 32918-2016 (in precedenza GM/T 0003-2012), che nella suite «SM» cinese svolge il ruolo che ECDSA/ECDH (P-256) svolgono nel mondo NIST.
L'ECC in un paragrafo (l'intuizione)

Tutta la crittografia a curve ellittiche si basa su un unico trucco: dato il punto base G su una curva su un grande campo primo e il multiplo P = d·G, calcolare d a partire da P significa risolvere il problema del logaritmo discreto sulla curva ellittica, per il quale non si conosce alcun algoritmo veloce. La chiave privata d è solo un numero a 256 bit; la chiave pubblica è il punto d·G. SM2 non è una nuova aritmetica di curva — è un modo specifico di firmare (come ECDSA) e cifrare (come un ECIES in miniatura) su una curva specifica, con hash SM3 invece di SHA.

sm2p256v1 contro NIST P-256
Aspettosm2p256v1NIST P-256 (secp256r1)
Dimensione del campoprimo a 256 bitprimo a 256 bit
Forma della curvay² = x³ + ax + by² = x³ − 3x + b (a = −3)
Livello di sicurezza≈ 128 bit≈ 128 bit
FirmaSM2 (GB/T 32918.2), basato su SM3, ID utente vincolato in ZAECDSA con SHA-256
CifraturaSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, non standardizzato dal NIST)
HashSM3 (GB/T 32905)famiglia SHA-2
Pubblicatoprogetto 2010, GM/T 0003-2012, GB/T 32918-2016; in ISO/IEC 14888-31999 (SEC 2 / NIST)
Supporto TLSTLCP (GM/T 386) e suite TLS 1.3 RFC 8998ovunque

Entrambe le curve offrono la stessa sicurezza concreta; nessuna ha un attacco pratico. La scelta tra le due è normativa e di interoperabilità, non di robustezza.

L'ID utente e ZA — ciò che SM2 firma e ECDSA non firma

Prima dell'hash, SM2 fonde l'identità del firmatario nel digest: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), dove ENTLa è la lunghezza in bit dell'ID, i quattro campi centrali fissano la curva esatta, e gli ultimi due sono la chiave pubblica del firmatario. Il messaggio viene sottoposto ad hash come SM3(ZA ‖ M). Due conseguenze: una firma è vincolata all'identità dichiarata (una caratteristica), e il verificatore deve conoscere l'ID del firmatario e usare lo stesso (un classico problema di interoperabilità). Quasi tutto l'ecosistema si è assestato sul predefinito di 16 cifre 1234567812345678 — non dal testo dello standard, ma dagli esempi dell'appendice di GM/T 0003; il default di OpenSSL coincide, e così questa pagina.

Formati del ciphertext: C1C3C2, C1C2C3 e DER

Un ciphertext SM2 ha tre parti: C1 = il punto effimero kG (64 byte, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 byte, integrità), C2 = M ⊕ KDF(x2 ‖ y2) (il messaggio mascherato). Il testo del 2012 GM/T 0003 li concatenava C1 ‖ C2 ‖ C3; lo standard GB/T 32918.4 del 2016 li ha riordinati in C1 ‖ C3 ‖ C2, e OpenSSL 1.1.1+ l'ha seguito. I vecchi sistemi bancari e governativi parlano ancora l'ordine precedente — per questo questa pagina ha entrambi, più la forma ASN.1 (SEQUENCE di INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2) che alcune librerie emettono. Quando la decifratura fallisce con lo strumento dell'altra parte, l'ordine dei byte è la prima cosa da controllare.

Errori comuni
  • Riusare o risparmiare sul k. Il nonce k nella firma e nella cifratura deve essere nuovo e imprevedibile per ogni operazione. Un k ripetuto in due firme consegna la chiave privata a chiunque veda entrambe. Questa pagina estrae k dal CSPRNG del browser; i campi del k fisso esistono solo per riprodurre vettori noti.
  • ID utente non corrispondenti. Firmi con l'ID predefinito e verifichi con uno personalizzato (o viceversa) e ogni firma valida fallisce. L'ID fa parte dei dati firmati.
  • Presumere C1C3C2 ovunque. I sistemi dell'epoca GM/T 0003, alcune smart card e le vecchie build di GmSSL usano C1C2C3 per impostazione predefinita; diversi strumenti antepongono anche un byte 04 di punto non compresso. Questa pagina accetta tutti questi formati in decifratura.
  • Cifrare dati di grandi dimensioni con SM2. Ogni ciphertext porta 96 byte di sovraccarico e costa due moltiplicazioni di punti. Usi SM2 su una chiave, SM4/AES sui dati.
  • Trattare una chiave pubblica con prefisso 04 come 65 byte grezzi di chiave. Il 04 è un marcatore di codifica: la chiave è x ‖ y, 128 cifre esadecimali. Questa pagina accetta entrambe le grafie.
FAQ

È compatibile con OpenSSL / GmSSL? Sì. L'output esadecimale C1C3C2 corrisponde a openssl pkeyutl -sm2encrypt per la stessa chiave pubblica, lo stesso messaggio e lo stesso k; le firme DER corrispondono byte per byte all'output di openssl dgst -sm3 -sign (imposti l'ID utente con -pkeyopt sm2_userid:...). Le esecuzioni con k casuale ovviamente differiscono — confronti decifrando/verificando, non per uguaglianza.

Perché qui non c'è lo scambio di chiavi SM2? La GB/T 32918.3 definisce un protocollo interattivo di scambio di chiavi autenticato; non ha senso come calcolatrice di una pagina. Firma e cifratura coprono gli usi non interattivi.

SM2 è in WebCrypto? No — nessun browser lo implementa (Chrome lo include solo dietro flag non standard, se affatto). Questa pagina esegue un'implementazione JavaScript scritta da zero, con i vettori dell'appendice dello standard stesso collegati all'autotest qui sopra.

Posso usare una chiave PEM di OpenSSL? Esporti invece il valore esadecimale grezzo: openssl ec -in key.pem -text stampa lo scalare privato e il punto pubblico. Questa pagina accetta solo chiavi esadecimali, di proposito — la parte PEM/SEC1 sta nella pagina RSA, dove deve stare.

Allora che cos'è SM9? Un animale diverso: la crittografia basata sull'identità, dove qualsiasi stringa (un indirizzo e-mail) è la chiave pubblica e un KGC emette le chiavi private. Veda la pagina di panoramica SM9.