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 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
|
支持的模式包括:CBC、CTR、CFB、OFB、ECB。
⚠️ 注意:不推荐使用 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 库)
- 政务系统数据加密
- 金融行业敏感数据保护
- 物联网设备安全通信
最佳实践#
- 始终使用 PBKDF2 密钥派生:使用
-pbkdf2 -iter 1000 或更高的迭代次数
- 使用 CBC 或 CTR 模式:避免使用 ECB 模式
- 每次加密使用随机盐值和 IV:不要重复使用相同的加密参数
- 安全存储密钥:使用密钥管理服务,不要硬编码密码
- 验证解密结果:解密后验证数据完整性
参考来源#
- 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