SM4 加密 / 解密

用 SM4 加密或解密 —— GB/T 32907-2016,中國國家 128 位分組密碼 —— 提供 ECB 與 CBC 兩種模式、PKCS#7 填充。輸出與 openssl enc -sm4-ecb / -sm4-cbc 逐位元組相容。全部在瀏覽器中執行;不會上傳任何資料。
始終應用 PKCS#7 填充,與 OpenSSL enc 完全一致。
按以下方式讀取輸入:
按以下方式輸出:
OpenSSL 交叉驗證 —— 在這裡加密,然後執行 openssl enc -d -sm4-cbc -K <hexkey> -iv <hexiv> -in file.sm4 -out file.txt(或去掉 -iv 用 -sm4-ecb):位元組完全一致,因為本頁使用的 PKCS#7 填充與 OpenSSL 相同。
自檢
重放 GB/T 32907-2016 附錄 A.1 已知答案向量、由獨立 Python 參考實現產出的六個確定性 ECB/CBC 交叉向量、全部四個示例池,以及反向路徑(錯誤金鑰長度、非分組整數倍的密文、被篡改的填充都必須被拒絕)。
什麼是 SM4?
一句話:SM4 是中國國家標準的分組密碼 —— 128 位分組、128 位金鑰、32 輪非平衡 Feistel 結構,釋出為 GB/T 32907-2016(前身 GM/T 0002-2012),在中國“SM”套件中扮演的角色正如 AES 在 NIST 世界裡的角色。
SM4 與 AES 一覽
方面SM4AES
分組大小128 位128 位
金鑰長度僅 128 位128 / 192 / 256 位
輪數3210 / 12 / 14
結構非平衡 Feistel(每輪更新一個 32 位字)代換–置換網路(每輪作用於整個狀態)
S 盒一個 8×8 盒,每輪用 4 次一個 8×8 盒,每輪用 16 次 + MixColumns
標準模式ECB、CBC(本頁);TLS 套件中的 GCM/CTR(RFC 8998)ECB、CBC、CTR、GCM……
釋出時間2012 年(GM/T 0002-2012;GB/T 32907-2016);已納入 ISO/IEC 18033-3:20102001 年(FIPS 197)

同一份工作,不同的設計:兩者都是帶公開 8×8 S 盒的 128 位分組密碼,但 SM4 迭代 32 輪輕量 Feistel,而 AES 施加 10–14 輪更重的整狀態變換。軟體實現中 AES 通常更快(得益於 AES-NI 硬體指令);SM4 則在中國平臺的專用 CPU 擴充套件上達到相當水準。兩者都沒有可行的攻擊;128 位金鑰就是 128 位金鑰。

為什麼用 SM4 而不是 AES?

為了合規與互操作,而不是強度:中國商用密碼法規要求受認證行業使用 SM 套件,TLCP 及帶 RFC 8998 套件的 TLS 1.3 等協議會協商 SM4。如果你的對手方、監管機構或硬體只認 SM4,那就用 SM4。如果可以自由選擇,本站 AES 頁面的 AES-256 仍是全球預設。

常見錯誤
  • 對結構化資料用 ECB。相同明文分組產生相同密文分組 —— 經典的企鵝圖。資料超過一個分組時,請用 CBC(本頁預設)並配新鮮的 IV。
  • 金鑰必須恰好 16 位元組。與 AES 不同,SM4 沒有 192/256 位變體。“password”這類口令不是金鑰 —— 請先用 KDF 派生(參見口令雜湊生成器)。
  • 以為填充是可選的。本頁與 OpenSSL enc 一樣總是應用 PKCS#7,因此 16 位元組明文會加密成 32 位元組。刻意不提供無填充的裸 SM4。
  • 在 CBC 中複用 IV。CBC 中重複的金鑰+IV 組合會洩露訊息字首的相等性。每條訊息生成隨機 IV,並把它與密文一起傳送。
常見問題

和 OpenSSL 相容嗎?相容 —— 逐位元組一致。openssl enc -sm4-cbc -K 0011... -iv 4455... -in in.txt -out out.sm4(OpenSSL 1.1.1+)對相同金鑰、IV 和輸入產出的密文與本頁列印的完全相同;GmSSL 亦然。

為什麼這裡沒有 SM4-GCM?標準周邊的庫生態主要在 TLS 棧內暴露 SM4-GCM;本頁對齊的面向檔案的命令列約定(enc)只覆蓋 ECB/CBC。帶認證的 SM4 屬於協議層的事。

WebCrypto 裡有 SM4 嗎?沒有 —— 沒有任何瀏覽器實現它。所以本頁用 JavaScript 從零實現,並把標準自帶的測試向量接進了上面的自檢。

能解密別處加密的內容嗎?能 —— 只要知道模式、金鑰、IV,並且確認用了 PKCS#7:把密文按 hex 或 Base64 貼上,切到“解密”即可。