Skip to content

SM4 暗号化・復号オンラインツール

SM4 の暗号化と復号をオンラインで。復号に失敗したら、モード・パディング・IV・エンコーディングのどれが合っていないかを突き止め、修正後の設定を示します。処理はブラウザ内で完結し、データはアップロードされません。ECB・CBC・CTR・CFB・OFB、PKCS#7・ゼロパディング・パディングなしに対応。

トラッキングなし ブラウザで動作 無料
暗号化はすべてブラウザ内で実行されます。入力した鍵とデータがこの端末の外に出ることはありません。
暗号文
同等の OpenSSL コマンド

OpenSSL 3 が必要です。コマンドには入力した鍵が含まれます。

GB/T 32907-2016 の SM4 テストベクトル

このページで動作するエンジンを使い、ビルド時に算出した値です。自作の SM4 実装をこれと照合してください。
0123456789abcdeffedcba9876543210
平文 0123456789abcdeffedcba9876543210
暗号文(1 回暗号化) 681edf34d206965e86b3e94f536e4246
暗号文(100 万回暗号化) 595298c7c6fd271f0402f804c33d3f66
SM4 エンジンは GB/T 32907-2016 付録 A の 2 つのテストベクトルでテストし、ECB・CBC・CTR・CFB・OFB の各モードで OpenSSL 3 と照合しています。ライブラリの既定値は、OpenSSL、Node.js、sm-crypto、gm-crypt、gmssl、2 つの Go ライブラリを実際に動かし、Hutool と BouncyCastle のソースコードを読んで確認しました。 — Go-Tools セキュリティチーム · Sep 11, 2026

暗号ツールを開発するエンジニアが執筆・レビューしています。このページに記載した暗号文とバイト数は、すべてツールのエンジンで算出し、テストで検証しています。

SM4 の要点まとめ

SM4 の鍵長

16 バイト ちょうど 128 ビット、つまり 16 バイトで、16 進数 32 桁または ASCII 16 文字で表記します。192 ビットや 256 ビットの SM4 鍵は存在しません。

GB/T 32907 テストベクトル

681edf34d206965e86b3e94f536e4246 鍵と平文を 0123456789abcdeffedcba9876543210 にすると、1 回の暗号化で 681edf34d206965e86b3e94f536e4246 になります。

SM4 のブロック長とラウンド数

32 ラウンド 16 バイト(128 ビット)のブロックを、32 ラウンドで暗号化します。

CBC で IV が間違っていると、必ずエラーになりますか?

先頭 16 バイト なりません。正しく復号できないのは先頭 16 バイトだけで、最後のブロックにあるパディングの検証は通ります。

SM4 とは?

SM4 は、中国の商用暗号標準(国密)に含まれるブロック暗号です。GM/T 0002-2012 として公布された後、国家標準 GB/T 32907-2016(2017 年 3 月 1 日施行)となり、2021 年の追補によって国際標準 ISO/IEC 18033-3 にも追加されました。暗号化と復号に同じ 128 ビットの鍵を使う共通鍵暗号で、128 ビット、つまり 16 バイト単位のブロックを処理します。ブロック長は AES と同じです。

内部では、各ブロックを 32 ビットのワード 4 つに分け、32 ラウンドの処理を行います。各ラウンドでは 3 つのワードをラウンド鍵と混ぜ、その結果を 8 ビットの S ボックスと線形変換に通してから、4 つ目のワードに畳み込みます。32 個のラウンド鍵は 2 組の固定定数を使って鍵から導出されます。復号は、ラウンド鍵を逆順に使うだけで暗号化と同じ計算です。

ブロック暗号そのものが扱えるのはちょうど 16 バイトだけなので、実際のデータは必ず暗号利用モードを通します。このツールは代表的な 5 つのモードに対応しています。ブロック単位で処理しパディングが必要な ECB と CBC、そして SM4 をストリーム暗号として使い、パディングが一切不要な CTR・CFB・OFB です。復号の失敗は、ほとんどの場合 SM4 自体とは関係ありません。モード、パディング、IV、テキストのエンコーディング、鍵文字列をバイト列にする方法について双方の認識が食い違っていることが原因です。単に「SM4」と書いたときに何を指すのかさえ、ライブラリ間で一致していません。

ブラウザ組み込みの Web Crypto API は SM4 に対応していないため、このページは独自の実装を持ち、ローカルで実行します。GB/T 32907 の 2 つのテストベクトルでテストし、すべてのモードで OpenSSL 3 と照合しています。

// SM4-CBC with PKCS#7 padding using Node.js and its bundled OpenSSL 3.
// Key and IV are both exactly 16 bytes (32 hex digits).
const crypto = require('node:crypto');

const key = Buffer.from('0123456789abcdeffedcba9876543210', 'hex');
const iv = Buffer.from('fedcba98765432100123456789abcdef', 'hex');

const cipher = crypto.createCipheriv('sm4-cbc', key, iv);
const ciphertext = Buffer.concat([cipher.update('hello', 'utf8'), cipher.final()]);
console.log(ciphertext.toString('base64')); // fUQPRg2HAXHGz5ZslzCpSQ==

const decipher = crypto.createDecipheriv('sm4-cbc', key, iv);
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
console.log(plaintext.toString('utf8')); // hello

SM4 ツールの主な機能

復号に失敗した理由がわかる

復号に失敗すると、暗号文のエンコーディング、鍵の形式、モード、IV、パディング、テキストのエンコーディングを変えて再試行し、読めるテキストになる設定を表示します。

トラブルの定番ライブラリをプリセットで再現

OpenSSL、Hutool、sm-crypto、gm-crypt、tjfoc/gmsm の既定値を 1 クリックで設定できます。これらのライブラリは、単に「SM4」と書いたときに ECB と CBC のどちらを指すのかさえ一致していません。

5 つのモード、3 種類のパディング、UTF-8 と GBK

ECB・CBC・CTR・CFB・OFB と、PKCS#7・ゼロパディング・パディングなしを組み合わせられます。平文は UTF-8 のほか、古い Java コードが中国語版 Windows 上で生成する GBK にも対応します。GCM には対応していません。

SM4 の鍵と IV:ランダム生成も、16 進数・テキスト・Base64 での入力も可能

16 バイトの鍵や IV を 1 クリックでランダム生成できるほか、コードに書かれている形式のまま入力することもできます。リアルタイムのバイト数カウンターで、ほかの原因を探し始める前に、ちょうど 16 バイトあることを確認できます。

GB/T 32907 テストベクトルをページに掲載

付録 A の 2 つの結果を表にまとめ、1 クリックで読み込めるようにしているので、どんな SM4 実装でも標準と照合できます。

同等の OpenSSL コマンド

すべての結果に、それを再現する openssl enc コマンドが付くので、ターミナルで確かめたり同僚に渡したりできます。

すべてブラウザ内で動作

SM4 エンジンはローカルで動作します。鍵やデータがページの外に出ることはなく、オフラインでも使い続けられます。

主要ライブラリにおける SM4 の既定値

OpenSSL 3(openssl enc

-sm4 = CBC

-sm4-sm4-cbc のエイリアスです。-K-iv は 16 進数で指定し、-nopad を渡さない限り PKCS#7 は有効のまま、-base64 -A を付けなければ出力は生のバイト列です。長さの合わない -K は、警告が出るだけで切り詰められるかゼロで埋められます。

Java: Hutool SmUtil.sm4(key)

ECB · PKCS#7

Hutool は SM4 という名前だけを渡し、BouncyCastle はそれを ECB と PKCS#7(JCE での名称は PKCS5Padding)で実行します。文字列メソッドは UTF-8 を使い、encryptHex は小文字の 16 進数を出力します。CBC を使うには new SM4(Mode.CBC, Padding.PKCS5Padding, key, iv) と書きます。

Java: BouncyCastle Cipher.getInstance("SM4")

ECB · PKCS#7

IV が必要なモードで IV を渡さないと、暗号化では黙ってランダムな IV が生成され、復号では no IV set when one expected がスローされます。つまり、その IV を保存せずに暗号化した暗号文は、どこでも復号できません。

JavaScript: sm-crypto

ECB · 16 進数の鍵

sm4.encrypt(data, key) の既定は ECB と PKCS#7 で、鍵には 32 桁の 16 進数文字列を想定し、小文字の 16 進数を返します。モードが変わるのは mode: 'cbc' を指定したときだけで、それ以外の値では黙って ECB のままになります。sm-crypto-v2 も同じ動作ですが、CBC で iv が渡されないとオールゼロの IV を使います。

JavaScript: gm-crypt

CBC · テキストの鍵 · Base64

既定は CBC で、鍵と IV を 16 文字の UTF-8 文字列として受け取り、Base64 を返します。バイト列が有効な UTF-8 にならない鍵は、そもそも渡すことができません。

Python: gmssl CryptSM4

PKCS#7 · 鍵は 16 バイトに切り詰め

モードは crypt_ecbcrypt_cbc のどちらを呼ぶかで選びます。set_key は先頭 16 バイトしか読まないため、長い鍵は黙って切り詰められます。また、鍵が間違っていても、たいていエラーではなく空のバイト列が返ります。

Go: tjfoc/gmsm sm4

既定はゼロ IV

Sm4Cbc はパッケージレベルの IV を使い、その IV は SetIV を呼ぶまでオールゼロのままです。CFB や OFB でも PKCS#7 でパディングし、パディング除去のエラーは破棄します。そのため鍵が間違っていても、エラーなしで nil が返ります。

SM4 暗号化・復号の例

GB/T 32907 テストベクトル(ECB、パディングなし)

鍵 0123456789abcdeffedcba9876543210、平文(hex)0123456789abcdeffedcba9876543210
681edf34d206965e86b3e94f536e4246

GB/T 32907-2016 付録 A の例 1 です。鍵と平文は同じ 128 ビットの値で、1 回暗号化すると 681edf34d206965e86b3e94f536e4246 になります。その出力をさらに暗号化し続け、合計 100 万回暗号化すると 595298c7c6fd271f0402f804c33d3f66 になります。どちらの値も、いま使っているのと同じエンジンで算出し、このページのテストベクトル表に掲載しています。GB/T 32907 テストベクトル ボタンで 1 つ目の値を読み込めます。

CBC と PKCS#7:テキストを入力し、Base64 で出力

鍵 0123456789abcdeffedcba9876543210、IV fedcba98765432100123456789abcdef、平文:SM4 interop test: order 20260911-0042
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y

平文は UTF-8 で 37 バイトです。PKCS#7 によって 48 バイト(16 バイトのブロック 3 つ)にパディングされ、Base64 では 64 文字になります。サンプルを読み込む ボタンを押すとまさにこの値が入力され、OpenSSL パネルには同じ Base64 文字列をターミナルで再現するコマンドが表示されます。

CBC で IV が違う:壊れるのは先頭 16 バイトだけ

上の暗号文を IV 00000000000000000000000000000000 で復号
16 バイト分の化けたデータの後に ": order 20260911-0042"

CBC で IV が混ざるのは最初のブロックだけで、PKCS#7 のパディングは最後のブロックにあります。そのためパディングのチェックは通り、OpenSSL もエラーを出しません。このページは先頭ブロックが読めないことを検知し、鍵とモードは正しく IV に問題があること、あるいは暗号文の先頭 16 バイトそのものが IV であることを知らせます。

SM4 暗号化・復号ツールの使い方

  1. 1

    ライブラリのプリセット、またはモードとパディングを選ぶ

    相手側のライブラリがわかっていれば、「ライブラリの既定値に合わせる」で選びます。わからなければ暗号化か復号を選び、モードとパディングを相手に合わせます。ストリームモード(CTR・CFB・OFB)にはパディングがないため、これらのモードではパディングの選択欄が無効になります。

  2. 2

    鍵と IV を入力する

    どちらもちょうど 16 バイトです。文字列の表記形式(16 進数・テキスト・Base64)を選び、バイト数カウンターが緑に変わることを確認します。「ランダム生成」ボタンで新しい値を作れます。

  3. 3

    入力を貼り付ける

    暗号化では、テキスト(UTF-8 または GBK)を入力するか、16 進数のバイト列を貼り付けます。復号では、暗号文を貼り付けて Base64 か 16 進数かを指定します。結果は入力と同時に更新されます。

  4. 4

    結果をコピーするか、往復で確認する

    出力をコピーするか、「この暗号文を復号」をクリックして、同じ鍵と IV のまま復号タブへ引き継ぎます。OpenSSL パネルには、結果を再現するコマンドが表示されます。

  5. 5

    復号に失敗したら診断結果を読む

    診断結果には、入力が読めるテキストに復号される設定が一覧表示されます。クリック 1 回で適用するか、先頭 16 バイトだけが失敗している場合は表示される注記を読んでください。それは IV が原因であることを示しています。

SM4 の復号に失敗する原因

16 進数の鍵をテキストとして読んでいる

32 文字の 16 進数文字列が 16 バイトになるのは、16 進数としてデコードした場合だけです。テキストとして読むと 32 バイトになり、SM4 に拒否されます。鍵を黙って切り詰めたり埋めたりするコードでは、まったく別の鍵として扱われます。

✗ 誤り
鍵(テキスト): 0123456789abcdeffedcba9876543210  -> 32 バイト、拒否される
✓ 正しい
鍵(16 進数):  0123456789abcdeffedcba9876543210  -> 16 バイト

CBC の暗号文を ECB として復号している

双方で同じモードを使う必要があります。CBC の暗号文を ECB として復号すると、すべてのブロックが化け、たいてい最後のパディングチェックでも失敗します。

✗ 誤り
暗号化: SM4/CBC/PKCS5Padding
復号:   SM4/ECB/PKCS5Padding  -> bad decrypt
✓ 正しい
暗号化: SM4/CBC/PKCS5Padding
復号:   SM4/CBC/PKCS5Padding、IV も同じ

異なる IV を使っている

CBC では IV が間違っていてもエラーは出ません。先頭 16 バイトが化け、残りは正常に復号されます。平文の冒頭だけが壊れているなら、双方の IV を比べてください。

✗ 誤り
復号 IV 00000000000000000000000000000000
-> 16 バイトの化けたデータ + ": order 20260911-0042"
✓ 正しい
復号 IV fedcba98765432100123456789abcdef
-> "SM4 interop test: order 20260911-0042"

Base64 の暗号文を 16 進数として扱っている

Base64 と 16 進数は、同じバイト列の 2 通りの書き方です。一方を他方として読むと、最初から間違った入力を暗号に渡すことになります。

✗ 誤り
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  16 進数として読む -> 無効
✓ 正しい
Wi6BuLpov8RndEfedUyLXFvDRnLMoo7T6O04Q83IzKDuDvPQ2S5clq+cEQXMvy/y  Base64 として読む -> 48 バイト

ゼロパディングが本物の末尾ゼロまで消してしまう

ゼロパディングはパディングとデータを区別できないため、本当に 0x00 で終わる平文はそのバイトを失います。プレーンテキスト以外のデータには PKCS#7 を使ってください。

✗ 誤り
ゼロパディング: 61 62 00  -> 復号結果 61 62
✓ 正しい
PKCS#7:         61 62 00  -> 復号結果 61 62 00

「SM4」がどこでも同じモードを指すと思い込んでいる

OpenSSL は sm4 を CBC として扱います。BouncyCastle と、それを使う Hutool の SmUtil.sm4(key) は、SM4 を ECB と PKCS#7 として扱います。どちらも「普通に SM4 を使っているだけ」の 2 つのシステムでも、モードが食い違うことがあります。

✗ 誤り
Java:    Cipher.getInstance("SM4")  -> ECB + PKCS#7
OpenSSL: openssl enc -sm4           -> CBC
✓ 正しい
Java:    Cipher.getInstance("SM4/CBC/PKCS5Padding")
OpenSSL: openssl enc -sm4-cbc

片方は GBK、もう片方は UTF-8 のバイト列で暗号化している

Java で文字コードを指定せずに getBytes() を呼ぶとプラットフォームの既定値が使われ、中国語版 Windows の JDK 17 以前では GBK になります。すると同じ中国語テキストでも暗号文が変わり、相手側では復号結果が文字化けします。

✗ 誤り
"国密SM4 test".getBytes()  // 中国語版 Windows の JDK <= 17 では GBK
-> ECB 暗号文 3188d06cf28db70092f8753cbd5ee518
✓ 正しい
"国密SM4 test".getBytes(StandardCharsets.UTF_8)
-> ECB 暗号文 d830308b0ae4fa7b9a2b5d59f7f65ca5

SM4 のオンライン暗号化が役立つ場面

バックエンドとフロントエンドで SM4 の出力を一致させる
Java のサービスと Web クライアントで、同じテキストから異なる暗号文ができてしまう。そんなときは、それぞれのライブラリのプリセットで両側をここで再現し、どのパラメーターが違うのかを確認できます。
連携先システムの復号失敗をデバッグする
連携先から届いた SM4 暗号文が復号できない。取り決めた鍵と IV と一緒に貼り付ければ、相手が実際に使ったモード、パディング、エンコーディングを診断機能が突き止めます。
SM4 実装を検証する
実装を本番データに近づける前に、このページの GB/T 32907 テストベクトルで自分のコードを確認し、続けて CBC の往復結果を比較します。
SM4 への移行に向けてテストデータを用意する
システムを AES から SM4 に移行するとき、既知の鍵・IV・暗号文の組をここで生成し、新しいテストのフィクスチャとして使えます。
ブロック暗号モードの挙動を確かめる
同一のブロック 2 つを ECB と CBC で暗号化したり、間違った IV で復号したりして、暗号文と出力の何が変わるかを観察できます。

SM4 と暗号利用モードの仕組み

ブロック長、鍵長、ラウンド数
SM4 は 128 ビットの鍵を使い、128 ビットのブロックを 32 ラウンドかけて暗号化します。各ラウンドでは 32 ビットのワードに 8 ビットの S ボックスを適用し、続いて、そのワードと自身を 4 通りに巡回シフトした値との XOR を取る線形変換を行います。復号では同じ 32 ラウンドを、ラウンド鍵を逆順にして実行します。
ECB:各ブロックを独立に処理
ECB は 16 バイトのブロックをそれぞれ独立に暗号化します。IV は不要ですが、同じ平文ブロックは同じ暗号文ブロックになるため、データのパターンが見えたままになります。入力が 16 バイトの倍数でない限り、パディングが必要です。
CBC:ブロックの連鎖と IV
CBC は各平文ブロックを暗号化する前に直前の暗号文ブロックと XOR し、最初のブロックには IV を使います。IV が関わるのは最初のブロックだけなので、IV が間違っていると平文の先頭 16 バイトだけが壊れ、最後のブロックにあるパディングは無傷のまま残ります。そのため、エラーがまったく出ないこともよくあります。
CTR・CFB・OFB:SM4 をストリーム暗号として使う
これらのモードはカウンターやフィードバック値を暗号化し、その結果をデータと XOR します。そのため暗号文は平文と同じ長さになり、パディングはありません。CTR では、OpenSSL と同じく 16 バイトの IV 全体を 1 つの 128 ビットのビッグエンディアンのカウンターとしてインクリメントします。IV が間違っていると、CTR と OFB ではメッセージ全体が化けますが、CFB では最初のブロックだけが化けます。
パディングの規則
PKCS#7 は値 n のバイトを 1〜16 個追加するので、すでにブロックの整数倍になっているメッセージにも 1 ブロック分のパディングが付きます。ゼロパディングは必要なときだけ 0x00 を追加し、復号時には末尾のゼロをすべて取り除きます。パディングなしではデータに手を加えず、ブロックの整数倍に満たない入力は拒否します。

SM4 暗号化のベストプラクティス

新規の設計では ECB を選ばない
ECB はどのブロックどうしが同じかを漏らします。すでに ECB を使っている既存システムに合わせる場合を除き、CBC か CTR を使ってください。
メッセージごとに新しいランダムな IV を使う
IV は秘密にする必要はありませんが、同じ鍵のもとで繰り返してはいけません。メッセージごとにランダムに生成し、暗号文と一緒に保存または送信してください。
暗号文を認証する
ブロック暗号の利用モードを定めた中国の標準 GB/T 17964-2021 は、そこに記載されたモードが守るのは機密性であって完全性ではない、と明記しています。CBC では IV の 1 バイトを変えるだけで pay=100.00pay=900.00 に変わり、それでも復号は成功します。IV と暗号文に対する MAC を計算し、復号の前に検証してください。たとえば HMAC ジェネレーターを使えます。
すべてのパラメーターをインターフェース仕様書に書く
「SM4 で暗号化」だけでは仕様とはいえません。モード、パディング、鍵と IV のエンコード方法、平文の文字コード、暗号文が 16 進数か Base64 かを明記してください。
本番の鍵を Web ページやソースコードに置かない
このページはテスト用の鍵で使ってください。本番の鍵は鍵管理システムやハードウェアセキュリティモジュール(HSM)で管理し、貼り付けたりコミットしたりせず、実行時に読み込むべきものです。

SM4 暗号化に関するよくある質問

SM4 の復号でパディングエラーや文字化けが起きるのはなぜですか?
復号が成功するのは、鍵のバイト列、モード、IV、パディング、そして暗号文の表記(16 進数か Base64 か)が、暗号化した側とすべて一致したときだけです。表示されるエラー(「bad decrypt」、パディング例外、あるいは画面いっぱいの文字化け)は、どれが違うのかを教えてくれません。ライブラリによっては、エラーを出さずに空の出力を返すこともあります。それでも、暗号文・鍵・IV をここに貼り付けてみてください。復号に失敗すると、このページは暗号文のエンコーディング、鍵の形式、モード、IV、パディングのあらゆる組み合わせを試します。ライブラリが黙って 16 バイトに切り詰めた鍵や、GBK でエンコードされた平文も対象です。そのうえで読めるテキストになった解釈を一覧にし、PKCS#7 パディングの検証に通ったものには印を付けます。先頭 16 バイトだけがおかしい場合、鍵とモードは正しく、IV が間違っています。
SM4 の鍵の長さは?256 ビットにできますか?
SM4 の鍵はちょうど 128 ビット、つまり 16 バイトで、ブロック長と同じです。GB/T 32907 が定める鍵長はこの 1 種類だけで、192 ビットや 256 ビットの SM4 は存在しません。256 ビットの SM4 鍵を求められたら、32 桁の 16 進数文字列を、1 文字 8 ビットの 32 文字として数えていないか確認してください。16 バイトは 16 進数 32 桁でも ASCII 16 文字でも書けるため、この 2 つの取り違えが鍵のミスで最も多いパターンです。0123456789abcdeffedcba9876543210 を 16 進数として読めば 16 バイトですが、同じ文字列をテキストとして読むと 32 バイトになり、拒否されます。鍵欄の横にある形式セレクターとバイト数カウンターは、まさにこのミスを防ぐためのものです。
SM4 の IV とは何ですか?長さはいくつ必要ですか?
IV(初期化ベクトル)は、CBC・CTR・CFB・OFB で最初のブロックに混ぜ込まれる 16 バイトの値で、ECB では使いません。長さはちょうど 16 バイト(16 進数 32 桁または ASCII 16 文字)でなければならないので、IV の長さエラーが出たら、32 桁の 16 進数文字列が 32 バイトのテキストとして読まれていないか確認してください。IV は秘密にする必要はありませんが、同じ鍵で使い回してはいけません。ランダムに生成し、暗号文と一緒に(多くの場合は暗号文の前に付けて)送ります。CBC で IV が間違っていても、たいていエラーは出ず、先頭 16 バイトが化けるだけです。IV が指定されないときに黙ってオールゼロの IV を使うライブラリ(sm-crypto-v2、Go の tjfoc/gmsm)がある一方、Java の BouncyCastle はランダムな IV を生成します。その IV を暗号文と一緒に保存していなければ、誰にも復号できません。
SM4 の ECB と CBC の違いは?どちらを使うべきですか?
メッセージごとに新しいランダムな IV を生成し、CBC(または CTR)を使ってください。ECB は同じ 16 バイトのブロックを同じ暗号文ブロックに変換するため、データ内の繰り返し構造が暗号文にそのまま現れます。ECB を選ぶのは、すでに ECB を使っているシステムと通信する場合だけにしましょう。なお、どちらのモードも改ざんは検知できません。改ざん対策が必要なら、IV と暗号文に対する MAC も併せて送ってください。たとえば HMAC ジェネレーターで計算できます。
SM4 のパディングは PKCS5Padding、PKCS#7、ゼロパディング、パディングなしのどれを使うべきですか?
PKCS#7 は常に 1〜16 バイトを追加し、各バイトに追加したバイト数を格納するので、受信側は曖昧さなく取り除けます。SM4 のような 16 バイトブロック暗号では、Java の PKCS5Padding も同じパディングです。BouncyCastle はどちらの名前も同じコードパスで処理します。ゼロパディングは、次のブロック境界まで 0x00 を追加するだけです。復号時、Hutool と BouncyCastle は末尾の 0x00 を、本来データの一部だったゼロバイトも含めてすべて取り除きますが、Python の gmssl は 1 バイトしか取り除きません。パディングなしの場合は、入力が 16 バイトブロックの整数倍である必要があります。CTR・CFB・OFB はストリームモードなので、パディングは一切行いません。復号したテキストの末尾に余計な空白、四角い記号、改行が付いているなら、パディングが除去されていません。PKCS#7 のデータをパディングなしで復号すると、値 n のバイトが末尾に n 個残ります(0x09、0x0A、0x0D はタブや改行として表示されます)。出力を Hex に切り替えて、最後のブロックを確認してください。
SM4 の暗号文の長さは?暗号文からモードを判別できますか?
バイト単位で数えます。ECB または CBC で PKCS#7 を使うと、平文は次の 16 の倍数に切り上げられ、すでに 16 の倍数であるメッセージにはさらに 1 ブロック分が追加されます。5 バイトや 15 バイトは 16 バイトに、16 バイトは 32 バイトになります。ゼロパディングは次の 16 の倍数まで埋めるだけで、パディングなしなら長さは変わらず、CTR・CFB・OFB の暗号文は平文とまったく同じ長さです。Hex ではバイト数の 2 倍の文字数になり、Base64 では 4 × ⌈バイト数 / 3⌉ 文字になるので、16 バイトは 24 文字、32 バイトは 44 文字、64 バイトは 88 文字です。IV を先頭に付けて送る場合は 16 バイトを足してください。暗号文だけではモードはわかりませんが、手がかりが 2 つあります。長さが 16 の倍数でなければ、パディングありの ECB や CBC はほぼ除外でき、同一の 16 バイトブロックが 2 つあれば ECB の可能性が高いといえます。確信が持てないときは復号タブに貼り付けてください。自動診断が各モードを試します。
SM4 は毎回同じ暗号文になりますか?ほかのツールと結果が違うのはなぜですか?
ECB、または IV を固定したモードでは、同じ鍵と平文から毎回同じ暗号文ができます。実行ごとに新しいランダムな IV を使えば出力は毎回変わり、それが正しい動作です。そのうえで比べるべき点は、モード、パディング、鍵を 16 進数とテキストのどちらとして読んだか、平文のエンコーディング(ほとんどのコードでは UTF-8 ですが、古い Java コードが中国語版 Windows 上で getBytes() を呼ぶと GBK になります)、そして結果の表記(Base64、小文字の 16 進数、大文字の 16 進数)です。設定をすべて揃えて IV を固定すれば、正しい実装どうしは同一の出力を返します。どちらかのツールを疑うなら、まず両方を GB/T 32907 のテストベクトルで確認してください。
自作の SM4 実装が正しいかどうか、どう確認すればよいですか?
まず GB/T 32907-2016 付録 A の 2 つのテストベクトルから始めます。鍵と平文をどちらも 0123456789abcdeffedcba9876543210 にしたとき、1 回の暗号化で 681edf34d206965e86b3e94f536e4246、100 万回の連続暗号化で 595298c7c6fd271f0402f804c33d3f66 にならなければなりません。これらが検証するのはブロック暗号の部分だけなので、次に鍵と IV を固定して CBC でテキストを暗号化し、このページの結果や、ページに表示される OpenSSL コマンドの結果と比較してください。このページのエンジンは、両方のテストベクトルと、5 つすべてのモードでの OpenSSL 3 との照合によってテストされています。
OpenSSL で SM4 の暗号化・復号はできますか?
できます。OpenSSL 3 は ECB・CBC・CFB・OFB・CTR の SM4 を搭載しています。openssl enc -sm4-cbc -K <32 hex digits> -iv <32 hex digits> のように使います。-K は生の鍵を 16 進数で受け取るのでパスワードは介在せず、-nopad で PKCS#7 を無効にでき、-base64 -A で 1 行の Base64 を読み書きします。注意点は 2 つあります。単に -sm4 と書くと CBC を意味すること、そして長さの合わない -K の値は、警告が出るだけで切り詰められるかゼロで埋められることです。このページの OpenSSL パネルは、現在の設定からコマンドを組み立てます。openssl enc にはゼロパディングがないため、その場合は一致しないコマンドを表示する代わりに、その旨を表示します。
Java(Hutool)や JavaScript(sm-crypto)で作られた SM4 暗号文を復号するには?
まず、相手側が実際にどのモードとパディングを使っているかを突き止めてください。コードに明記されていないことがよくあります。Hutool の SmUtil.sm4(key)SM4 という名前しか渡さず、BouncyCastle はそれを ECB と PKCS#7(Java でいう PKCS5Padding)で補います。CBC になるのは、SM4/CBC/PKCS5Padding のように完全な文字列を指定した場合だけです。JavaScript では、sm-crypto も既定は ECB で、鍵を 32 桁の 16 進数文字列で受け取り、小文字の 16 進数を出力します。一方 gm-crypt は既定が CBC で、16 文字のテキスト鍵を受け取り、Base64 を出力します。次に平文の文字コードを確認します。Hutool の文字列メソッドは常に UTF-8 を使いますが、中国語版 Windows 上の JDK 17 以前で引数なしの getBytes() を呼ぶと GBK になることがあり、暗号文が変わります。ライブラリの既定値に合わせる でライブラリを選べばこれらを 1 クリックで設定でき、手動で入力することもできます。どれかが不確かでも、まず暗号文を貼り付けてください。自動診断がモード、パディング、IV、エンコーディングの組み合わせを試します。
SM4 は安全ですか?データはアップロードされますか?
アルゴリズムとしての SM4 は、128 ビットの鍵と 32 ラウンドを用います。RFC 8998(2021 年)は、執筆時点で SM4 に弱い鍵やセキュリティ上の問題は知られていないと述べています。実際のリスクは使い方から生じます。ECB はパターンを漏らし、CBC は改ざんを検知しません。このページについて言えば、何もアップロードされません。ブラウザは SM4 を標準搭載していないため、このページは独自の SM4 実装を持ち、ローカルで実行します。ネットワークパネルを開いてリクエストが一切送信されないことを確かめることも、ネット接続を切ったままツールを使い続けることもできます。そのため、テストデータ、デバッグ、学習には問題なく使えます。ただし、だからといって本番環境の鍵を扱う場所として Web ページが適切になるわけではありません。本番の鍵は、どんな Web サイトのテキストボックスでもなく、鍵管理システムやハードウェアモジュールで管理すべきものです。
SM4 と AES の違いは何ですか?
どちらも 128 ビットブロックのブロック暗号で、モードとパディングの仕組みも共通です。SM4 の相互運用バグが AES のものとそっくりに見えるのはそのためです。SM4 は 32 ラウンドで、鍵長は 128 ビットの 1 種類だけです。AES-128 は 10 ラウンドで、AES には 192 ビットと 256 ビットの鍵もあります。SM4 は中国の国家標準 GB/T 32907-2016 であり、2021 年からは国際標準 ISO/IEC 18033-3 にも AES と並んで収録されています。中国の商用暗号(国密)が求められる場面で使われます。AES は NIST の標準 FIPS 197 です。AES を扱うなら AES 暗号化ツールをご利用ください。

AES復号ツール — OpenSSL・CryptoJS互換

セキュリティツール

AESをオンラインで復号 — GCM/CBC/CTR、パスフレーズまたは生鍵に対応し、OpenSSLとCryptoJSの「U2FsdGVkX1」形式を自動検出します。処理は100%ブラウザ内で完結し、鍵がこのページから出ることはありません。

AES暗号化ツール — GCM・CBC・CTR対応

セキュリティツール

無料のAESオンライン暗号化ツール — AES-128/192/256、GCM/CBC/CTR、パスフレーズ(PBKDF2)または生鍵に対応。処理は100%ブラウザ内で完結し、外部にアップロードされません。

Bcrypt ハッシュ生成・検証ツール

セキュリティツール

bcrypt パスワードハッシュをオンラインで生成・検証。コスト調整、$2b$/$2a$/$2y$ プレフィックス対応。100% ブラウザ内で処理し、パスワードは一切送信されません。

CRC チェックサム計算機(巡回冗長検査)

セキュリティツール

16進数またはテキストを貼り付けるだけで、CRC-8・CRC-16・CRC-32 の全63変種を一度に算出します。手元のチェックサムと一致しない場合は期待値を入力すれば、MODBUS・CCITT-FALSE・XMODEM・KERMIT のどれかを自動で特定。処理はすべてブラウザ内で完結します。

HMAC ジェネレーター&署名検証ツール

セキュリティツール

無料のオンライン HMAC 生成・検証ツール。Text・Hex・Base64 の鍵で HMAC-SHA256/SHA1/SHA384/SHA512 を計算し、Hex/Base64/Base64URL で出力します。100% ブラウザ内で完結 —— 鍵はページから外に出ません。

JWT デコーダー — オンライン解析ツール

セキュリティツール

JWTトークンを無料のJWTデコーダーでオンラインデコード。ヘッダー、ペイロード、署名、有効期限、アルゴリズム、クレームを即座に検査できます。100%ブラウザ動作 — トークンはデバイスから外に出ません。登録不要、追跡なし。