SM2 szyfrowanie / deszyfrowanie / podpis

Pełny zestaw narzędzi SM2 z kluczem publicznym na zalecanej krzywej sm2p256v1 (GB/T 32918.5): generowanie pary kluczy, podpisywanie i weryfikacja schematem ZA opartym na SM3 (GB/T 32918.2) oraz szyfrowanie i deszyfrowanie w standardowej kolejności C1C3C2, w starszej kolejności C1C2C3 albo w ASN.1 DER. Wszystko działa w przeglądarce; nic nie jest wysyłane.
Klucz prywatny (hex, 64 cyfry — traktuj jak hasło)
Klucz publiczny (hex, 130 cyfr z prefiksem 04 albo 128 cyfr x||y)
Klucz prywatny używany jest przez Podpisz i Deszyfruj; klucz publiczny przez Weryfikuj i Szyfruj. Klucze nigdy nie opuszczają tej strony.
Identyfikator użytkownika(„identyfikator rozróżniający” wplatany w ZA; domyślny to de facto standard)
Odczytaj wiadomość jako: Stałe k (zaawansowane):
r (hex)
s (hex)
Podpis, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } — format używany przez OpenSSL/GmSSL)
O polu stałego k: każdy prawdziwy podpis musi używać świeżego, nieprzewidywalnego k — ponowne użycie lub zgadnięcie k ujawnia klucz prywatny (lekcja z ECDSA u Sony). Ta strona generuje losowe k z crypto.getRandomValues, gdy pole jest puste. Wypełniaj je wyłącznie po to, by odtworzyć znany wektor do nauki lub testów.
Identyfikator użytkownika(musi być zgodne z podpisującym)
Odczytaj wiadomość jako: Format podpisu:
r (hex)
s (hex)
✓ Podpis jest POPRAWNY
✗ Podpis jest NIEPOPRAWNY
Odczytaj wiadomość jako: Format szyfrogramu: Wynik:
Stałe k (zaawansowane):
Przypomnienie o szyfrowaniu hybrydowym: szyfrowanie SM2 służy do krótkich sekretów (kluczy sesji, PIN-ów), a nie dużych danych — każda wiadomość płaci 96 bajtów narzutu C1+C3 i mnożenie punktu na krzywej eliptycznej. Zaszyfruj losowy klucz SM4/AES kluczem SM2, a dane symetrycznym szyfrem (strona SM4 / strona AES).
Odczytaj szyfrogram jako: Rząd: Zapisz tekst jawny jako:
Weryfikacja krzyżowa z OpenSSL — szesnastkowy wynik C1C3C2 tej strony zgadza się z openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x z -pkeyopt ec_scheme:c1c3c2, domyślny), oraz z narzędziami GmSSL gmssl sm2randkey / sm2encrypt; podpisy zgadzają się z openssl dgst -sm3 -sign przy tym samym identyfikatorze użytkownika ustawionym przez -pkeyopt sm2_userid:1234567812345678. Bajt 04 przed C1 (tak tworzą go niektóre biblioteki) jest akceptowany przy deszyfrowaniu.
Uwaga o zgodności: SM2 to wybór algorytmu podyktowany chińską zgodnością z komercyjną kryptografią i interoperacyjnością; bezpieczeństwo jest porównywalne z ECC 256-bitowym (NIST P-256). W produkcji łącz go z prawdziwym systemem zarządzania kluczami lub kluczami sprzętowymi — strona w przeglądarce to kalkulator, a nie skarbiec.
Autotest
Odtwarza wektory wyprowadzania klucza, podpisu ze stałym k i szyfrowania, wytworzone przez niezależną implementację referencyjną w Pythonie (i sprawdzone krzyżowo z gmssl), cykle DER podpisu i szyfrogramu DER, cykle sign/verify i encrypt/decrypt z losowym k oraz ścieżki negatywne (zmieniony C3, obcięty szyfrogram, klucz publiczny spoza krzywej, r = 0).
Czym jest SM2?
W jednym zdaniu: SM2 to chiński krajowy standard kryptosystemu klucza publicznego — schemat podpisu i szyfrowania na krzywej eliptycznej o stałych parametrach sm2p256v1, opublikowany jako GB/T 32918-2016 (wcześniej GM/T 0003-2012); w chińskim pakiecie „SM” pełni rolę, jaką w świecie NIST pełnią ECDSA/ECDH (P-256).
ECC jednym akapitem (intuicja)

Cała kryptografia krzywych eliptycznych opiera się na jednej sztuczce: mając punkt bazowy G na krzywej nad dużym polem pierwszym i wielokrotność P = d·G, obliczenie d z P oznacza rozwiązanie problemu logarytmu dyskretnego na krzywej eliptycznej, dla którego nie znano szybkiego algorytmu. Klucz prywatny d to po prostu 256-bitowa liczba; klucz publiczny to punkt d·G. SM2 nie wprowadza nowej arytmetyki krzywej — to konkretny sposób podpisywania (jak ECDSA) i szyfrowania (jak miniaturowe ECIES) na jednej konkretnej krzywej, z haszowaniem SM3 zamiast SHA.

sm2p256v1 a NIST P-256
Aspektsm2p256v1NIST P-256 (secp256r1)
Rozmiar pola256-bitowa liczba pierwsza256-bitowa liczba pierwsza
Kształt krzywejy² = x³ + ax + by² = x³ − 3x + b (a = −3)
Poziom bezpieczeństwa≈ 128 bitów≈ 128 bitów
PodpisSM2 (GB/T 32918.2), oparty na SM3, identyfikator użytkownika wplątany w ZAECDSA z SHA-256
SzyfrowanieSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, nie standaryzowany przez NIST)
SkrótSM3 (GB/T 32905)rodzina SHA-2
Opublikowanyprojekt z 2010 roku, GM/T 0003-2012, GB/T 32918-2016; w ISO/IEC 14888-31999 (SEC 2 / NIST)
obsługa TLSTLCP (GM/T 386) i zestawy TLS 1.3 RFC 8998wszędzie

Obie krzywe oferują tę samą konkretną siłę; żadna nie ma praktycznego ataku. Wybór między nimi wynika z przepisów i interoperacyjności, a nie z siły.

Identyfikator użytkownika i ZA — co SM2 podpisuje, a czego nie podpisuje ECDSA

Przed haszowaniem SM2 wplata tożsamość podpisującego w skrót: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), gdzie ENTLa to długość ID w bitach, środkowe cztery pola przypinają dokładną krzywą, a dwa ostatnie to klucz publiczny podpisującego. Wiadomość haszuje się jako SM3(ZA ‖ M). Dwie konsekwencje: podpis jest związany z deklarowaną tożsamością (cecha), a weryfikator musi znać ID podpisującego i użyć tego samego (klasyczna pułapka interoperacyjności). Niemal cały ekosystem przyjął 16-cyfrowy domyślny 1234567812345678 — nie z tekstu standardu, ale z przykładów w dodatku GM/T 0003; domyślna wartość OpenSSL się z tym zgadza, tak samo jak ta strona.

Formaty szyfrogramu: C1C3C2, C1C2C3 i DER

Szyfrogram SM2 ma trzy części: C1 = efemeryczny punkt kG (64 bajty, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 bajty, integralność), C2 = M ⊕ KDF(x2 ‖ y2) (zamaskowana wiadomość). Tekst GM/T 0003 z 2012 roku łączył je jako C1 ‖ C2 ‖ C3; standard GB/T 32918.4 z 2016 roku zmienił kolejność na C1 ‖ C3 ‖ C2, a OpenSSL 1.1.1+ poszedł za nim. Stare systemy bankowe i rządowe nadal mówią w starej kolejności — dlatego ta strona obsługuje obie, plus postać ASN.1 (SEQUENCE z INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2), którą emitują niektóre biblioteki. Gdy deszyfrowanie zawodzi przy narzędziu drugiej strony, kolejność bajtów jest pierwszą rzeczą do sprawdzenia.

Typowe błędy
  • Ponowne użycie lub oszczędzanie na k. Nonce k zarówno w podpisywaniu, jak i szyfrowaniu musi być świeże i nieprzewidywalne przy każdej operacji. Jedno powtórzone k w dwóch podpisach oddaje klucz prywatny każdemu, kto widzi oba. Ta strona losuje k z CSPRNG przeglądarki; pola stałego k istnieją wyłącznie po to, by odtwarzać znane wektory.
  • Niezgodne identyfikatory użytkownika. Podpisz z domyślnym identyfikatorem, weryfikuj z własnym (lub odwrotnie), a każdy poprawny podpis zawiedzie. Identyfikator jest częścią podpisywanych danych.
  • Zakładanie C1C3C2 wszędzie. Systemy z ery GM/T 0003, niektóre karty chipowe i starsze wersje GmSSL domyślnie używają C1C2C3; kilka narzędzi dodaje też bajt 04 oznaczający nieskompresowany punkt. Ta strona akceptuje wszystkie te warianty przy deszyfrowaniu.
  • Szyfrowanie dużych danych przez SM2. Każdy szyfrogram niesie 96 bajtów narzutu i kosztuje dwa mnożenia punktów. Używaj SM2 na klucz, a SM4/AES na dane.
  • Traktowanie klucza publicznego z prefiksem 04 jako 65 surowych bajtów klucza. Bajt 04 to znacznik kodowania: sam klucz to x ‖ y, 128 cyfr szesnastkowych. Ta strona akceptuje obie postacie.
FAQ

Czy to jest zgodne z OpenSSL / GmSSL? Tak. Szesnastkowe wyjście C1C3C2 zgadza się z openssl pkeyutl -sm2encrypt dla tego samego klucza publicznego, wiadomości i k; podpisy DER zgadzają się bajt po bajcie z wyjściem openssl dgst -sm3 -sign (ID użytkownika ustawia się przez -pkeyopt sm2_userid:...). Przebiegi z losowym k oczywiście się różnią — porównuj przez deszyfrowanie lub weryfikację, a nie równość.

Dlaczego tu nie ma wymiany kluczy SM2? GB/T 32918.3 definiuje interaktywny, uwierzytelniony protokół uzgadniania klucza; nie ma sensu jako jednostronicowy kalkulator. Podpis i szyfrowanie obejmują zastosowania nieinteraktywne.

Czy SM2 jest w WebCrypto? Nie — żadna przeglądarka go nie implementuje (Chrome dostarcza go co najwyżej za niestandardowymi flagami). Ta strona działa na implementacji w JavaScript pisanej od zera, z wektorami z dodatku standardu podłączonymi do samotestu powyżej.

Czy mogę użyć klucza PEM z OpenSSL? Zamiast tego eksportuj surowy hex: openssl ec -in key.pem -text wypisuje skalar prywatny i punkt publiczny. Ta strona przyjmuje wyłącznie klucze hex, celowo — mechanika PEM/SEC1 znajduje się na stronie RSA, gdzie jej miejsce.

Czym jest więc SM9? Innym zwierzęciem: kryptografia oparta na tożsamości, w której dowolny ciąg (np. adres e-mail) jest kluczem publicznym, a KGC wystawia klucze prywatne. Zob. stronę przeglądu SM9.