SM2 暗号化 / 復号 / 署名

推奨曲線 sm2p256v1(GB/T 32918.5)上の完全な SM2 公開鍵ツールボックス:鍵ペアの生成、SM3 ベースの ZA 方式による署名・検証(GB/T 32918.2)、標準の C1C3C2 順、レガシーの C1C2C3 順、ASN.1 DER での暗号化・復号。すべてブラウザー内で実行され、アップロードは一切ありません。
秘密鍵 (hex、64 桁 — パスワードのように扱ってください)
公開鍵 (hex、04 接頭辞付き 130 桁または x||y の 128 桁)
秘密鍵は署名と復号で、公開鍵は検証と暗号化で使われます。鍵がこのページから出ることはありません。
ユーザー ID(ZA に混ぜ込まれる「識別識別子」。既定は事実上の標準値)
メッセージの読み方: 固定 k(上級):
r (hex)
s (hex)
署名、ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } - OpenSSL/GmSSL が使う形式)
固定 k ボックスについて:本物の署名は毎回新しく予測不可能な k を使わなければなりません — k の再利用や推測は秘密鍵を漏らします(Sony の ECDSA 教訓)。ボックスが空の間、このページは crypto.getRandomValues からランダムな k を生成します。ボックスを埋めるのは、教育やテストで既知ベクトルを再現するときだけにしてください。
ユーザー ID(署名者と一致していなければなりません)
メッセージの読み方: 署名形式:
r (hex)
s (hex)
✓ 署名は有効です
✗ 署名は無効です
メッセージの読み方: 暗文形式: 出力:
固定 k(上級):
ハイブリッド暗号化の注意:SM2 暗号化は短い秘密(セッション鍵、PIN)のためのものであり、大量データ向けではありません — すべてのメッセージが C1+C3 の 96 バイトのオーバーヘッドと 1 回の楕円曲線の点乗算を払います。ランダムな SM4/AES 鍵を SM2 で暗号化し、データを共通鍵暗号で暗号化してください(SM4 ページ / AES ページ)。
暗文の読み方: 順序: 平文の書き方:
OpenSSL 相互チェック — このページの C1C3C2 hex は openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem(OpenSSL 3.x で -pkeyopt ec_scheme:c1c3c2、既定)および GmSSL の gmssl sm2randkey / sm2encrypt ツールと一致し、署名は同じユーザー ID で -pkeyopt sm2_userid:1234567812345678 を付けて openssl dgst -sm3 -sign と一致します。C1 の前の先頭 04 バイト(いくつかのライブラリが生成する形)は復号時に受け付けます。
コンプライアンス注記:SM2 は中国の商用暗号コンプライアンスと相互運用に基づくアルゴリズムの選択で、セキュリティは 256 ビット ECC(NIST P-256)に相当します。本番では本物の鍵管理システムやハードウェア鍵と組み合わせてください — ブラウザーページは電卓であってボールトではありません。
セルフテスト
独立した Python リファレンス実装が生成した(gmssl と相互確認済みの)鍵導出、固定 k 署名、暗号化のベクトル、 DER 署名と DER 暗文のラウンドトリップ、ランダム k の署名/検証・暗号化/復号のラウンドトリップ、 そして陰性パス(改ざんされた C3、切り詰められた暗文、曲線外の公開鍵、r = 0)を再生します。
SM2 とは?
一言で言えば:SM2 は中国国家標準の公開鍵暗号方式です — 固定曲線 sm2p256v1 上の楕円曲線署名・暗号化方式で、GB/T 32918-2016(以前の GM/T 0003-2012)として公開され、NIST の世界で ECDSA/ECDH(P-256)が果たす役割を中国の「SM」スイートの中で果たします。
楕円曲線暗号を 1 段落で(直感)

すべての楕円曲線暗号は 1 つのトリックの上に成り立ちます:大きな素数体上の曲線の基準点 G と、その倍点 P = d·G が与えられたとき、P から d を求めることは楕円曲線離散対数問題を解くことで、その高速なアルゴリズムは知られていません。秘密鍵 d は単なる 256 ビットの数で、公開鍵は点 d·G です。SM2 は新しい曲線演算ではなく — 特定の 1 つの曲線の上で、署名(ECDSA 的)と暗号化(小型 ECIES 的)を行う特定の方式であり、SHA の代わりに SM3 でハッシュします。

sm2p256v1 対 NIST P-256
観点sm2p256v1NIST P-256(secp256r1)
体のサイズ256 ビット素数256 ビット素数
曲線の形状y² = x³ + ax + by² = x³ − 3x + b(a = −3)
セキュリティレベル約 128 ビット約 128 ビット
署名SM2(GB/T 32918.2)、SM3 ベース、ユーザー ID が ZA に結合SHA-256 付き ECDSA
暗号化SM2(GB/T 32918.4)、C1C3C2ECIES(ANSI X9.63、NIST 標準化なし)
ハッシュSM3(GB/T 32905)SHA-2 ファミリー
公開2010 年設計、GM/T 0003-2012、GB/T 32918-2016。ISO/IEC 14888-3 収録1999 年(SEC 2 / NIST)
TLS 対応TLCP(GM/T 386)と TLS 1.3 RFC 8998 スイートどこでも

両曲線は同じ具体的セキュリティを提供し、どちらにも実用的な攻撃はありません。選択は強度ではなく規制と相互運用性の問題です。

ユーザー ID と ZA — SM2 が ECDSA にないものとして署名するもの

ハッシュの前に、SM2 は署名者の ID をダイジェストに折り込みます: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA)。ENTLa は ID のビット長、中間の 4 項目が正確な曲線を固定し、最後の 2 項目は署名者の公開鍵です。メッセージは SM3(ZA ‖ M) としてハッシュされます。2 つの帰結:署名は主張された ID に結合される(機能)、そして検証者は署名者の ID を告げられ同じものを使わなければならない(古典的な相互運用の落とし穴)。ほぼエコシステム全体が 16 桁の既定値 1234567812345678 に落ち着きました — 規格本文ではなく GM/T 0003 の付録例から。OpenSSL の既定もそれに一致し、このページも同様です。

暗文形式:C1C3C2、C1C2C3、DER

SM2 の暗文は 3 部構成です:C1 = 一時点 kG(64 バイト、x‖y)、 C3 = SM3(x2 ‖ M ‖ y2)(32 バイト、完全性)、C2 = M ⊕ KDF(x2 ‖ y2)(マスクされたメッセージ)。2012 年の GM/T 0003 本文は C1 ‖ C2 ‖ C3 と連結しましたが、2016 年の GB/T 32918.4 規格は C1 ‖ C3 ‖ C2 に並べ替え、OpenSSL 1.1.1+ がそれに従いました。旧銀行・政府システムは今も旧順序を話します — だからこそこのページは両方に加え、一部のライブラリが吐く ASN.1 形式(INTEGER x1、INTEGER y1、OCTET STRING C3、OCTET STRING C2 の SEQUENCE)を持っています。相手のツールで復号に失敗したら、まずバイト順を確認してください。

よくある間違い
  • k の再利用や切り詰め。署名と暗号化のノンス k は、操作ごとに新しく予測不可能でなければなりません。2 つの署名にわたって 1 つの k を繰り返すと、両方を見た人に秘密鍵を渡します。このページはブラウザーの CSPRNG から k を取り、固定 k ボックスは既知ベクトルの再現専用です。
  • ユーザー ID の不一致。既定の ID で署名し、カスタム ID で検証すると(またはその逆)、有効な署名すべてが失敗します。ID は署名データの一部です。
  • どこでも C1C3C2 と仮定する。GM/T 0003 時代のシステム、一部のスマートカード、古い GmSSL ビルドは既定で C1C2C3 を使います。いくつかのツールは非圧縮点の 04 バイトを先頭に付けます。このページは復号時にこれらすべてを受け付けます。
  • SM2 で大量データを暗号化する。各暗文は 96 バイトのオーバーヘッドを運び、2 回の点乗算を費やします。鍵には SM2、データには SM4/AES を。
  • 04 接頭辞付きの公開鍵を 65 バイトの生鍵として扱う。04 はエンコードのマーカーです:鍵自体は x ‖ y の 128 hex 桁。このページは両方の書き方を受け付けます。
よくある質問

OpenSSL / GmSSL と互換がありますか?はい。C1C3C2 の hex 出力は同じ公開鍵・メッセージ・k での openssl pkeyutl -sm2encrypt と一致し、DER 署名は openssl dgst -sm3 -sign の出力とバイト単位で一致します(-pkeyopt sm2_userid:... でユーザー ID を設定)。ランダム k の実行はもちろん毎回異なります — 等しさではなく復号/検証で比較してください。

なぜ SM2 鍵交換がないのですか?GB/T 32918.3 は対話型の認証付き鍵交換プロトコルを定義します。1 ページの電卓として意味をなしません。署名と暗号化が非対話の用途をカバーします。

SM2 は WebCrypto にありますか?いいえ — ブラウザーはどれも実装していません(Chrome は非標準フラグの後ろで出荷する程度)。このページはゼロから書いた JavaScript 実装で、規格自身の付録ベクトルを上のセルフテストに組み込んでいます。

OpenSSL の PEM 鍵は使えますか?代わりに生の hex を書き出してください:openssl ec -in key.pem -text が秘密スカラーと公開点を印字します。このページは意図的に hex 鍵のみ受け付けます — PEM/SEC1 の機構はそれが属するRSA ページにあります。

では SM9 とは?別の生き物です:ID ベース暗号 — 任意の文字列(メールアドレス)がそのまま公開鍵であり、KGC が秘密鍵を発行します。SM9 概要ページを参照。