中国商用暗号SM2完全ガイド:鍵生成、暗号化・復号、デジタル署名の実践

SM2とは?

SM2は中国国家暗号管理局が発表した非対称暗号アルゴリズムで、楕円曲線暗号(ECC)をベースに、RSAに代わる中国商用暗号(国密)標準となっています。

比較項目 SM2 RSA 2048
鍵長 256 bit 2048 bit
セキュリティ強度 128 bit 112 bit
署名速度 ~0.5ms ~3ms
検証速度 ~1ms ~0.1ms
鍵長の比率 1 8
標準規格 GM/T 0003 PKCS#1

SM2は256ビットの鍵でRSA 2048ビット相当のセキュリティ強度を実現し、鍵が短く、処理も高速です。


SM2の3つの用途

用途 説明 対応ツール
暗号化/復号 公開鍵で暗号化し、秘密鍵で復号 SM2暗号化
デジタル署名 秘密鍵で署名し、公開鍵で検証 SM2署名
鍵共有 両者で共有鍵を協商する ECDHプロトコル

ステップ1:SM2鍵ペアの生成

ToolsKuで生成

  1. SM2暗号化ツールを開く
  2. 「鍵ペア生成」をクリック
  3. 公開鍵と秘密鍵を取得

コマンドラインで生成

# gmssl をインストール
brew install gmssl  # macOS
# または https://github.com/guanzhi/GmSSL/releases からダウンロード

# SM2鍵ペアを生成
gmssl sm2 -genkey -out sm2.key

# 鍵を表示
gmssl sm2 -in sm2.key -text

JavaScriptで生成

import { sm2 } from 'sm-crypto';

// 鍵ペアを生成
const keyPair = sm2.generateKeyPairHex();
// keyPair.privateKey → 秘密鍵(64桁の16進数)
// keyPair.publicKey  → 公開鍵(128桁の16進数、04 + X + Y)

console.log('秘密鍵:', keyPair.privateKey);
console.log('公開鍵:', keyPair.publicKey);

鍵フォーマットの説明

SM2公開鍵フォーマット:
04 || X(32バイト) || Y(32バイト)
↓
04 + 64桁の16進数X + 64桁の16進数Y
合計長:130文字の16進数(65バイト)

SM2秘密鍵フォーマット:
32バイトの乱数
合計長:64文字の16進数(32バイト)

ステップ2:SM2の暗号化と復号

暗号化の流れ

平文 → SM2暗号化(公開鍵) → 暗号文(C1 || C3 || C2)
  • C1:楕円曲線上の点(65バイト)
  • C3:SM3ハッシュ値(32バイト)
  • C2:暗号文データ

ToolsKuで暗号化

  1. SM2暗号化ツールを開く
  2. 公開鍵を貼り付ける
  3. 暗号化する平文を入力
  4. 暗号文フォーマットを選択(C1C3C2 または C1C2C3)
  5. 「暗号化」をクリックして暗号文を取得

JavaScriptで暗号化

import { sm2 } from 'sm-crypto';

const publicKey = '04...'; // 130桁の16進数
const privateKey = '...';  // 64桁の16進数

// 暗号化(デフォルトは C1C3C2 フォーマット)
const cipherText = sm2.doEncrypt('Hello 国密', publicKey, 1);
// 引数 1 = C1C3C2 フォーマット(国標推奨)
// 引数 0 = C1C2C3 フォーマット(旧版との互換用)

console.log('暗号文:', cipherText);

// 復号
const plainText = sm2.doDecrypt(cipherText, privateKey, 1);
console.log('平文:', plainText); // "Hello 国密"

暗号文のエンコードフォーマット

フォーマット 説明 使用シーン
C1C3C2 国標推奨フォーマット 新規プロジェクト(デフォルト)
C1C2C3 旧フォーマット 旧システムとの互換
ASN.1 DERエンコード Java/C# との相互運用

ステップ3:SM2デジタル署名

署名の流れ

メッセージ → SM3ハッシュ → SM2署名(秘密鍵) → 署名値(r, s)

ToolsKuで署名

  1. SM2暗号化ツールを開く
  2. 「署名」タブに切り替える
  3. 秘密鍵と署名対象メッセージを入力
  4. 「署名」をクリックして署名値を取得

JavaScriptで署名

import { sm2 } from 'sm-crypto';

const privateKey = '...';
const publicKey = '04...';

// 署名(メッセージに自動でSM3ハッシュを適用)
const signature = sm2.doSignature('署名対象メッセージ', privateKey);
console.log('署名:', signature);

// 署名を検証
const verified = sm2.doVerifySignature(
  '署名対象メッセージ',
  signature,
  publicKey
);
console.log('検証結果:', verified); // true

ユーザーID付き署名

SM2署名はデフォルトでユーザーID 1234567812345678(国標のデフォルト値)を使用しますが、カスタマイズ可能です:

// 署名時にユーザーIDを指定
const sig = sm2.doSignature('メッセージ', privateKey, {
  userId: 'customUserId'
});

// 検証時に同じユーザーIDを使用
const valid = sm2.doVerifySignature('メッセージ', sig, publicKey, {
  userId: 'customUserId'
});

SM2 vs RSA:どちらを選ぶべきか?

シナリオ 推奨 理由
中国の政府系システム SM2 国密コンプライアンス要件
中国の金融システム SM2 銀聯/中国人民銀行の要件
国際標準システム RSA 国際的な互換性
モバイル端末の暗号化 SM2 鍵が短く、計算が速い
越境データ交換 RSA 国際的に広く利用可能

中国商用暗号3点セット:SM2 + SM3 + SM4

アルゴリズム タイプ 用途 ツール
SM2 非対称 暗号化/署名/鍵共有 SM2ツール
SM3 ハッシュ メッセージダイジェスト(SHA-256相当) SM3ツール
SM4 対称 データ暗号化(AES-128相当) SM4ツール

典型的な組み合わせ:SM2 + SM4 ハイブリッド暗号

1. ランダムなSM4鍵を生成
2. SM4で大容量データを暗号化(高速)
3. SM2公開鍵でSM4鍵を暗号化(安全に送信)
4. 送信:SM2(SM4鍵) + SM4(データ)
import { sm2, sm4 } from 'sm-crypto';

// 1. ランダムなSM4鍵を生成
const sm4Key = crypto.getRandomValues(new Uint8Array(16));
const sm4KeyHex = Array.from(sm4Key).map(b => b.toString(16).padStart(2, '0')).join('');

// 2. SM4でデータを暗号化
const encryptedData = sm4.encrypt(plainText, sm4KeyHex);

// 3. SM2でSM4鍵を暗号化
const encryptedKey = sm2.doEncrypt(sm4KeyHex, sm2PublicKey, 1);

// 送信:encryptedKey + encryptedData

よくある質問

SM2の暗号文はなぜ平文よりずっと長いの?

SM2の暗号文 = C1(65バイト)+ C3(32バイト)+ C2(平文の長さ)のため、暗号文は平文より97バイト長くなります。これは非対称暗号の特性です。大容量データにはSM2+SM4ハイブリッド暗号を推奨します。

SM2とECDSAの違いは?

SM2は国密指定の楕円曲線(sm2p256v1)を使用し、ECDSAはNIST曲線(P-256)を使用します。アルゴリズムのロジックは似ていますが、曲線パラメータが異なるため、互換性はありません。

JavaでSM2を使うには?

// Bouncy Castle + 国密拡張を使用
Security.addProvider(new BouncyCastleProvider());

// 鍵ペアを生成
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
kpg.initialize(new ECParameterSpec(...)); // SM2曲線パラメータ
KeyPair kp = kpg.generateKeyPair();

まとめ

SM2は中国商用暗号体系の中核となる非対称暗号アルゴリズムで、256ビットの鍵でRSA 2048ビット相当のセキュリティ強度を実現します。鍵生成、暗号化・復号、デジタル署名の3つの操作をマスターし、SM3ハッシュやSM4対称暗号と組み合わせれば、国密コンプライアンス要件を満たせます。ToolsKuはSM2、SM3、SM4の3つのオンラインツールを提供しており、ブラウザ内でローカル処理されるため、データが外部に送信されることはありません。

#国密#SM2#非对称加密#数字签名#加密教程