SM4 是中国国家密码管理局发布的分组密码算法,于 2006 年正式发布为行业标准。2012 年被采纳为国家标准(GB/T 32907-2016),2021 年成为 ISO/IEC 标准(ISO/IEC 18033-3:2010/Amd.1:2021)。

作为国密算法的重要组成部分,SM4 被广泛应用于政府、金融、电信等对数据安全有高要求的领域。本文介绍如何在 OpenSSL 中使用 SM4 算法进行数据加密。

环境要求

OpenSSL 3.0 及以上版本原生支持 SM4 算法,无需额外安装 GmSSL。

1
openssl version

输出:

1
OpenSSL 3.0.19 27 Jan 2026 (Library: OpenSSL 3.0.19)

查看支持的 SM4 模式:

1
openssl list -cipher-algorithms | grep SM4

输出:

1
2
3
4
5
6
sm4 => SM4-CBC
  SM4-CBC
  SM4-CFB
  SM4-CTR
  SM4-ECB
  SM4-OFB

支持的模式包括:CBCCTRCFBOFBECB

⚠️ 注意:不推荐使用 ECB 模式,因为它会产生相同的密文块,容易泄露数据模式。

SM4-CBC 加密解密

SM4-CBC 是最常用的模式,结合 PKCS#5/PKCS#7 填充实现安全加密。

加密文件

1
2
3
4
openssl enc -sm4-cbc -salt -pbkdf2 -iter 1000 \
    -in plaintext.txt \
    -out ciphertext.bin \
    -pass pass:your_password

参数说明:

  • -sm4-cbc:使用 SM4 算法,CBC 模式
  • -salt:添加随机盐值,增强安全性
  • -pbkdf2 -iter 1000:使用 PBKDF2 密钥派生函数,迭代 1000 次
  • -pass pass::指定密码(生产环境建议使用 -pass file:-pass env:

解密文件

1
2
3
4
openssl enc -sm4-cbc -d -pbkdf2 -iter 1000 \
    -in ciphertext.bin \
    -out decrypted.txt \
    -pass pass:your_password

使用 Base64 编码

如果需要文本形式的密文(便于传输或存储在配置文件中),可以使用 -a 选项:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 加密并输出 Base64
openssl enc -sm4-cbc -salt -pbkdf2 -iter 1000 -a \
    -in plaintext.txt \
    -out ciphertext.txt \
    -pass pass:your_password

# 解密 Base64 密文
openssl enc -sm4-cbc -d -pbkdf2 -iter 1000 -a \
    -in ciphertext.txt \
    -out decrypted.txt \
    -pass pass:your_password

完整示例:

1
2
3
4
5
6
7
# 加密
$ echo "这是一条需要加密的敏感数据" | openssl enc -sm4-cbc -salt -pbkdf2 -iter 1000 -a -pass pass:secret123
U2FsdGVkX1+ABCD1234EFGH5678IJKL==

# 解密
$ echo "U2FsdGVkX1+ABCD1234EFGH5678IJKL==" | openssl enc -sm4-cbc -d -pbkdf2 -iter 1000 -a -pass pass:secret123
这是一条需要加密的敏感数据

SM4-CTR 模式

CTR(Counter)模式将密码转换为流密码,无需填充。适用于需要实时加密或数据长度不确定的场景。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 加密
openssl enc -sm4-ctr -pbkdf2 -iter 1000 -a \
    -in plaintext.txt \
    -out ciphertext.txt \
    -pass pass:your_password

# 解密
openssl enc -sm4-ctr -d -pbkdf2 -iter 1000 -a \
    -in ciphertext.txt \
    -out decrypted.txt \
    -pass pass:your_password

示例:

1
2
3
4
5
$ echo "SM4 CTR mode test" | openssl enc -sm4-ctr -pbkdf2 -iter 1000 -a -pass pass:test123
U2FsdGVkX1/abcdefghijklmnopqrstuv==

$ echo "U2FsdGVkX1/abcdefghijklmnopqrstuv==" | openssl enc -sm4-ctr -d -pbkdf2 -iter 1000 -a -pass pass:test123
SM4 CTR mode test

手动指定密钥和 IV

对于需要精确控制密钥的场景,可以手动指定 16 字节密钥和 16 字节 IV:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 生成 16 字节密钥(128 位)
KEY=$(openssl rand -hex 16)

# 生成 16 字节 IV
IV=$(openssl rand -hex 16)

# 加密(使用十六进制 key 和 iv)
echo "敏感数据" | openssl enc -sm4-cbc -K $KEY -iv $IV -a

# 解密
echo "密文" | openssl enc -sm4-cbc -d -K $KEY -iv $IV -a

完整示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ KEY=$(openssl rand -hex 16)
$ IV=$(openssl rand -hex 16)
$ echo "Key: $KEY"
Key: 2ec03238821027ca8ea4f717ca1b130a
$ echo "IV: $IV"
IV: 0bc6c6e117b976f257ef28f9d79414eb

$ echo "Secret data" | openssl enc -sm4-cbc -K $KEY -iv $IV -a
YHwxAlhQXQZs/VYyisgAcQ==

$ echo "YHwxAlhQXQZs/VYyisgAcQ==" | openssl enc -sm4-cbc -d -K $KEY -iv $IV -a
Secret data

⚠️ 安全提示:每次加密建议使用不同的随机 IV。密钥应安全存储,建议使用密钥管理服务或硬件安全模块(HSM)。

与其他对称算法对比

特性 SM4 AES-256
密钥长度 128 位 128/192/256 位
分组长度 128 位 128 位
国密合规 ✅ 必须 ⚠️ 国内政务、金融受限
硬件支持 逐步支持 广泛支持
OpenSSL 支持 3.0+ 原生 所有版本

在国密合规场景下,必须使用 SM4 算法替代国际算法。常见应用场景包括:

  • 国密 SSL/TLS 通信(需要 GmSSL 或支持国密的 TLS 库)
  • 政务系统数据加密
  • 金融行业敏感数据保护
  • 物联网设备安全通信

最佳实践

  1. 始终使用 PBKDF2 密钥派生:使用 -pbkdf2 -iter 1000 或更高的迭代次数
  2. 使用 CBC 或 CTR 模式:避免使用 ECB 模式
  3. 每次加密使用随机盐值和 IV:不要重复使用相同的加密参数
  4. 安全存储密钥:使用密钥管理服务,不要硬编码密码
  5. 验证解密结果:解密后验证数据完整性

参考来源

  • OpenSSL 官方文档:https://www.openssl.org/docs/manmaster/man1/openssl-enc.html
  • GM/T 0002-2012:SM4 分组密码算法(国家密码管理局)
  • ISO/IEC 18033-3:2010/Amd.1:2021:Information security — Encryption algorithms — Part 3: Block ciphers