SM2 Enkripsi / Dekripsi / Tanda Tangan

Perangkat lengkap kunci publik SM2 pada kurva yang direkomendasikan sm2p256v1 (GB/T 32918.5): buat pasangan kunci, tanda tangani dan verifikasi dengan skema ZA berbasis SM3 (GB/T 32918.2), dan enkripsi atau dekripsi dalam urutan standar C1C3C2, urutan lama C1C2C3, atau ASN.1 DER. Semuanya berjalan di browser; tidak ada yang diunggah.
Kunci privat (hex, 64 digit — perlakukan seperti kata sandi)
Kunci publik (hex, 130 digit dengan awalan 04 atau 128 digit x||y)
Kunci privat digunakan oleh Tanda Tangani dan Dekripsi; kunci publik oleh Verifikasi dan Enkripsi. Kunci tidak pernah meninggalkan halaman ini.
ID Pengguna("pengenal pembeda" yang dicampur ke dalam ZA; default adalah standar de facto)
Baca pesan sebagai: k tetap (lanjutan):
r (hex)
s (hex)
Tanda tangan, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } - format yang digunakan OpenSSL/GmSSL)
Tentang kotak k tetap: setiap tanda tangan sungguhan harus menggunakan k baru yang tidak dapat diprediksi — menggunakan ulang atau menebak k membocorkan kunci privat (pelajaran ECDSA Sony). Halaman ini membuat k acak dari crypto.getRandomValues setiap kali kotak kosong. Isi kotak hanya untuk mereproduksi vektor yang sudah diketahui untuk pengajaran atau pengujian.
ID Pengguna(harus sama dengan milik penandatangan)
Baca pesan sebagai: Format tanda tangan:
r (hex)
s (hex)
✓ Tanda tangan VALID
✗ Tanda tangan TIDAK VALID
Baca pesan sebagai: Format ciphertext: Output:
k tetap (lanjutan):
Pengingat enkripsi hibrida: enkripsi SM2 dimaksudkan untuk rahasia pendek (kunci sesi, PIN), bukan data besar — setiap pesan membayar 96 byte overhead C1+C3 dan satu perkalian titik kurva elips. Enkripsi kunci SM4/AES acak dengan SM2, lalu data dengan cipher simetris (halaman SM4 / halaman AES).
Baca ciphertext sebagai: Orde: Tulis plaintext sebagai:
Pemeriksaan silang OpenSSL — hex C1C3C2 halaman ini cocok dengan openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x dengan -pkeyopt ec_scheme:c1c3c2, bawaan), dan perkakas GmSSL gmssl sm2randkey / sm2encrypt; tanda tangan cocok dengan openssl dgst -sm3 -sign dengan ID pengguna yang sama melalui -pkeyopt sm2_userid:1234567812345678. Byte 04 di depan C1 (seperti yang dihasilkan beberapa pustaka) diterima saat dekripsi.
Catatan kepatuhan: SM2 adalah pilihan algoritma yang didorong oleh kepatuhan kriptografi komersial Tiongkok dan interoperasi, dengan keamanan yang setara dengan ECC 256-bit (NIST P-256). Dalam produksi, pasangkan dengan sistem manajemen kunci sungguhan atau kunci perangkat keras — halaman peramban adalah kalkulator, bukan brankas.
Uji mandiri
Memutar ulang vektor derivasi kunci, tanda tangan k tetap, dan enkripsi yang dihasilkan oleh implementasi referensi Python independen (dan diperiksa silang dengan gmssl), roundtrip tanda tangan DER dan ciphertext DER, roundtrip tanda tangan/verifikasi dan enkripsi/dekripsi k acak, serta jalur negatif (C3 yang dimanipulasi, ciphertext terpotong, kunci publik di luar kurva, r = 0).
Apa itu SM2?
Dalam satu kalimat: SM2 adalah sistem kriptografi kunci publik standar nasional Tiongkok — skema tanda tangan dan enkripsi kurva elips atas kurva tetap sm2p256v1, diterbitkan sebagai GB/T 32918-2016 (sebelumnya GM/T 0003-2012), memainkan peran dalam rangkaian "SM" Tiongkok yang sama dengan peran ECDSA/ECDH (P-256) di dunia NIST.
ECC dalam satu paragraf (intuisinya)

Semua kriptografi kurva elips bertumpu pada satu trik: diberi titik dasar G pada kurva di atas medan bilangan prima besar dan kelipatan P = d·G, menghitung d dari P berarti menyelesaikan masalah logaritma diskret kurva elips, yang tidak diketahui algoritma cepatnya. Kunci privat d hanyalah bilangan 256-bit; kunci publik adalah titik d·G. SM2 bukan aritmetika kurva baru — ia adalah cara tertentu untuk menandatangani (seperti ECDSA) dan mengenkripsi (seperti ECIES mini) pada satu kurva tertentu, dengan hash SM3 alih-alih SHA.

sm2p256v1 vs NIST P-256
Aspeksm2p256v1NIST P-256 (secp256r1)
Ukuran medanbilangan prima 256-bitbilangan prima 256-bit
Bentuk kurvay² = x³ + ax + by² = x³ − 3x + b (a = −3)
Tingkat keamanan≈ 128 bit≈ 128 bit
Tanda tanganSM2 (GB/T 32918.2), berbasis SM3, ID pengguna terikat ke ZAECDSA dengan SHA-256
EnkripsiSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, tidak distandarkan NIST)
HashSM3 (GB/T 32905)Keluarga SHA-2
DipublikasikanDesain 2010, GM/T 0003-2012, GB/T 32918-2016; dalam ISO/IEC 14888-31999 (SEC 2 / NIST)
Dukungan TLSTLCP (GM/T 386) dan suite TLS 1.3 RFC 8998di mana-mana

Kedua kurva menawarkan keamanan konkret yang sama; tidak ada yang memiliki serangan praktis. Pilihan di antara keduanya bersifat regulasi dan interoperabilitas, bukan kekuatan.

ID pengguna dan ZA — apa yang ditandatangani SM2 yang tidak ditandatangani ECDSA

Sebelum hashing, SM2 memasukkan identitas penandatangan ke dalam digest: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), dengan ENTLa adalah panjang bit dari ID, empat bidang di tengah mengunci kurva yang tepat, dan dua bidang terakhir adalah kunci publik penandatangan. Pesan di-hash sebagai SM3(ZA ‖ M). Dua konsekuensi: tanda tangan terikat pada identitas yang diklaim (suatu fitur), dan pemverifikasi harus diberi tahu ID penandatangan dan menggunakan yang sama (jebakan interop klasik). Hampir seluruh ekosistem menetap pada default 16 digit 1234567812345678 — bukan dari teks standar, melainkan dari contoh lampiran GM/T 0003; default OpenSSL cocok dengannya, dan demikian juga halaman ini.

Format ciphertext: C1C3C2, C1C2C3, dan DER

Ciphertext SM2 memiliki tiga bagian: C1 = titik sementara kG (64 byte, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 byte, integritas), C2 = M ⊕ KDF(x2 ‖ y2) (pesan yang di-mask). Teks GM/T 0003 tahun 2012 menggabungkannya sebagai C1 ‖ C2 ‖ C3; standar GB/T 32918.4 tahun 2016 mengurutkan ulang menjadi C1 ‖ C3 ‖ C2, dan OpenSSL 1.1.1+ mengikutinya. Sistem perbankan dan pemerintahan lama masih menggunakan urutan lama — itulah sebabnya halaman ini menyediakan keduanya, plus bentuk ASN.1 (SEQUENCE dari INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2) yang dikeluarkan beberapa pustaka. Ketika dekripsi gagal dengan alat pihak lain, urutan byte adalah hal pertama yang diperiksa.

Kesalahan umum
  • Menggunakan ulang atau menghemat k. Nonce k dalam penandatanganan maupun enkripsi harus baru dan tidak dapat diprediksi untuk setiap operasi. Satu k yang berulang di dua tanda tangan memberikan kunci privat kepada siapa pun yang melihat keduanya. Halaman ini mengambil k dari CSPRNG peramban; kotak k tetap hanya ada untuk mereproduksi vektor yang sudah diketahui.
  • ID pengguna yang tidak cocok. Tanda tangani dengan ID bawaan, verifikasi dengan ID kustom (atau sebaliknya) dan setiap tanda tangan yang valid akan gagal. ID adalah bagian dari data yang ditandatangani.
  • Mengasumsikan C1C3C2 di mana-mana. Sistem era GM/T 0003, beberapa kartu pintar, dan build GmSSL yang lebih lama secara bawaan menggunakan C1C2C3; beberapa alat juga menambahkan byte titik tanpa kompresi 04 di depan. Halaman ini menerima semua ini saat dekripsi.
  • Mengenkripsi data besar dengan SM2. Setiap ciphertext membawa 96 byte overhead dan memerlukan dua perkalian titik. Gunakan SM2 pada kunci, SM4/AES pada data.
  • Memperlakukan kunci publik berawalan 04 sebagai 65 byte kunci mentah. 04 adalah penanda pengodean: kuncinya sendiri adalah x ‖ y, 128 digit hex. Halaman ini menerima kedua ejaan ini.
FAQ

Apakah ini kompatibel dengan OpenSSL / GmSSL? Ya. Output hex C1C3C2 cocok dengan openssl pkeyutl -sm2encrypt untuk kunci publik, pesan, dan k yang sama; tanda tangan DER cocok dengan keluaran openssl dgst -sm3 -sign byte demi byte (atur ID pengguna dengan -pkeyopt sm2_userid:...). Eksekusi dengan k acak tentu berbeda — bandingkan dengan dekripsi/verifikasi, bukan dengan kesamaan.

Mengapa tidak ada pertukaran kunci SM2 di sini? GB/T 32918.3 mendefinisikan protokol pertukaran kunci terautentikasi interaktif; itu tidak masuk akal sebagai kalkulator satu halaman. Tanda tangan dan enkripsi mencakup penggunaan non-interaktif.

Apakah SM2 ada di WebCrypto? Tidak — tidak ada peramban yang mengimplementasikannya (Chrome hanya menyediakannya di balik flag non-standar, jika memang ada). Halaman ini menjalankan implementasi JavaScript dari awal, dengan vektor lampiran standar itu sendiri dihubungkan ke self-test di atas.

Bisakah kunci PEM dari OpenSSL digunakan? Ekspor hex mentahnya sebagai gantinya: openssl ec -in key.pem -text mencetak skalar privat dan titik publik. Halaman ini hanya menerima kunci hex, dengan sengaja — mesin PEM/SEC1 berada di halaman RSA tempat seharusnya.

Lalu apa SM9? Hewan yang berbeda: kriptografi berbasis identitas, di mana string apa pun (alamat surel) adalah kunci publik dan KGC menerbitkan kunci privat. Lihat halaman ikhtisar SM9.