SM系列密码算法是中国国家密码管理局(简称“国密局”)制定和发布的一系列商用密码算法标准,旨在保障国家信息安全,构建自主可控的安全体系。这套算法在金融、政府、物联网、区块链等众多领域得到广泛应用。
核心算法概览
SM系列主要包括以下核心算法:
算法名称 | 全称 | 类型 | 对标国际算法 | 简要描述 |
---|---|---|---|---|
SM1 | 对称分组密码算法 | 对称加密 | AES | 分组长度和密钥长度均为128位。算法不公开,通过硬件芯片实现。 |
SM2 | 椭圆曲线公钥密码算法 | 非对称加密 | ECC (ECDSA/ECDH) | 基于椭圆曲线密码学(ECC),用于数字签名、密钥交换和公钥加密。 |
SM3 | 密码杂凑算法 | 哈希算法 | SHA-256 | 输出长度为256位(32字节)的杂凑值。用于数字签名和消息认证。 |
SM4 | 对称分组密码算法 | 对称加密 | AES | 分组长度和密钥长度均为128位。算法公开,软件和硬件均可实现。 |
SM7 | 分组密码算法 | 对称加密 | - | 适用于非接触式IC卡应用,如门禁、一卡通等。 |
SM9 | 标识密码算法 | 非对称加密 | - | 基于标识的密码系统(IBC),用户标识(如邮箱、手机号)即为公钥,简化密钥管理。 |
ZUC(祖冲之) | 序列密码算法 | 流加密 | SNOW 3G | 主要用于4G/5G移动通信中的国际加密和完整性保护算法。 |
接下来,我们将重点讲解最常用且算法公开的SM2、SM3、SM4。
1. SM2:椭圆曲线公钥密码算法
SM2是基于椭圆曲线密码学(ECC)的公钥算法。相比RSA,在相同安全强度下,ECC所需的密钥长度更短(例如256位SM2约等于3072位RSA),计算更快,带宽占用更小。
核心组件:
-
椭圆曲线参数: 使用一条特定的椭圆曲线,其方程通常为 $y^2 = x^3 + ax + b$ over $F_p$(素数域)。国密局推荐了一套标准参数(包括素数p、系数a、b、基点G、阶n等)。
-
密钥对:
-
私钥(d): 一个在 [1, n-1] 范围内随机选取的整数。
-
公钥(P): 私钥对应的点,通过计算 $P = d \cdot G$(G的d倍点乘)得到。
-
三大功能:
-
数字签名
-
签名生成: 对消息M,使用私钥d和SM3哈希算法生成签名(r, s)。
-
签名验证: 使用公钥P、消息M和签名(r, s)来验证签名的有效性。
-
-
密钥交换
-
两方(A和B)可以通过交换一些信息,并结合自己的私钥和对方的公钥,协商出一个只有双方才知道的共享密钥(Session Key),用于后续的对称加密通信。
-
-
公钥加密
-
加密: 使用接收方的公钥P对消息M进行加密,生成密文C。
-
解密: 接收方使用自己的私钥d对密文C进行解密,恢复出原始消息M。
-
简单代码示例(使用Python的gmssl
库):
from gmssl import sm2, func
# 1. 初始化(可以使用默认曲线参数)
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)
# 2. 数据加密和解密
data = b"This is the message to be encrypted"
enc_data = sm2_crypt.encrypt(data)
dec_data = sm2_crypt.decrypt(enc_data)
print(f"Decrypted: {dec_data.decode()}")
# 3. 数字签名和验证
random_hex_str = func.random_hex(sm2_crypt.para_len)
sign = sm2_crypt.sign(data, random_hex_str)
assert sm2_crypt.verify(sign, data) # 验证成功则无异常
2. SM3:密码杂凑算法
SM3是一种密码学哈希函数,可将任意长度的输入消息压缩成固定长度(256位)的摘要(哈希值)。其设计结构与SHA-256类似,但具体设计存在差异。
-
特性: 单向性、抗碰撞性、雪崩效应。
-
应用:
-
与SM2结合用于数字签名。
-
生成消息认证码(MAC)。
-
保护数据完整性。
-
简单代码示例:
from gmssl import sm3
def sm3_hash_bytes(data):
"""计算字节数据的SM3哈希值"""
return sm3.sm3_hash(list(data))
# 测试
data = b"Hello, World! This is SM3."
hash_result = sm3_hash_bytes(data)
print(f"原始数据: {data.decode()}")
print(f"SM3 Hash: {hash_result}")
print(f"哈希长度: {len(hash_result)} 字符") # SM3输出64个十六进制字符
3. SM4:对称分组密码算法
SM4是一种分组密码算法,用于替代DES/3DES和AES。它采用32轮迭代的非平衡Feistel结构。
-
分组长度: 128位
-
密钥长度: 128位
-
模式: 支持ECB、CBC、CFB、OFB、CTR等标准工作模式。
-
应用: 大量数据的加密,如文件加密、通信信道加密。
加解密过程(以CBC模式为例):
-
密钥扩展: 将输入的128位主密钥扩展成32个32位的轮密钥。
-
加密(多轮): 每一轮操作包括非线性τ变换、线性变换L、轮异或等。
-
解密: 解密算法与加密算法相同,只是轮密钥的使用顺序相反。
简单代码示例:
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT
import binascii
key = b'3l5butlj26hvv313' # 16 bytes key
iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # 16 bytes IV for CBC
crypt_sm4 = CryptSM4()
# 加密
plaintext = b'This is a secret message'
crypt_sm4.set_key(key, SM4_ENCRYPT)
ciphertext = crypt_sm4.crypt_cbc(iv, plaintext)
print(f"Ciphertext (hex): {binascii.hexlify(ciphertext)}")
# 解密
crypt_sm4.set_key(key, SM4_DECRYPT)
decrypted_text = crypt_sm4.crypt_cbc(iv, ciphertext)
print(f"Decrypted: {decrypted_text.decode()}")
总结与学习路径
-
理解基础: 首先确保理解对称加密、非对称加密、哈希函数的基本概念。
-
从SM3/SM4开始: 它们的应用和概念(如分组、模式)与SHA系列和AES类似,更容易上手。
-
攻克SM2: 需要一些椭圆曲线密码学的基础数学知识(有限域、点加、点乘),但使用现有库时可以暂时忽略其复杂实现。
-
实践:
-
使用现有的国密库(如GmSSL、TongSuo)进行编程实践。
-
尝试实现一个简单的“SM2签名+SM4加密”的数据安全传输流程:
-
用SM3对消息取哈希。
-
用SM2私钥对哈希值签名。
-
生成一个随机的SM4会话密钥。
-
用SM4加密原始消息。
-
用接收方的SM2公钥加密刚才的SM4会话密钥。
-
将签名、加密后的消息、加密后的会话密钥一起发送给对方。
-
-
重要资源:
-
国家密码管理局官网: 查找标准文档(但算法细节通常在标准文本中)。
-
GmSSL项目: 一个开源的密码工具箱,支持SM2/SM3/SM4/SM9等国密算法。(https://github.com/guanzhi/GmSSL)
-
TongSuo(铜锁): 蚂蚁集团开源的密码学库,源自OpenSSL,提供对国密算法的强大支持。(Hello from OpenAtom 铜锁/Tongsuo | OpenAtom 铜锁/Tongsuo)
希望这份教程能帮助您系统地入门中国SM系列密码算法!