国密算法库(gmssl)入门:安装、基本用法、SM2密钥生成示例
做国密开发,绕不开一个库——gmssl。它封装了SM2/SM3/SM4等国密标准,Python调用起来非常方便。我个人习惯用gmssl做原型验证,因为它够轻量,文档也还算清晰。这节咱们就把它装好、跑一遍,再生成一对SM2密钥。
gmssl是什么?为什么选它?
gmssl是国密算法的Python实现,底层依赖OpenSSL,但接口更Pythonic。我在项目中对比过好几个国密库,最后选gmssl的原因很简单:
- 纯Python接口,不用理解复杂的C代码
- 同时支持SM2/SM3/SM4,一个库搞定
- 社区活跃,遇到问题容易搜到解决方案
说到底,它帮我们省去了手搓椭圆曲线算法的麻烦,咱们只需调API就行。
安装gmssl
安装非常简单,一条命令搞定:
pip install gmssl
如果你在国内,加个镜像源会快很多:
pip install gmssl -i https://pypi.tuna.tsinghua.edu.cn/simple
装完之后验证一下:
python -c "import gmssl; print(gmssl.__version__)"
我见过有人装了之后报ImportError: No module named 'gmssl',多半是pip和python版本对不上。建议用虚拟环境,避免污染系统Python。
基本用法快速上手
gmssl主要提供三个核心模块:
| 模块 | 说明 | 常用类/函数 |
|---|---|---|
gmssl.sm2 | SM2非对称加密/签名 | SM2Key, CryptSM2, Sign |
gmssl.sm3 | SM3哈希 | sm3_hash |
gmssl.sm4 | SM4对称加密 | CryptSM4, SM4_ENCRYPT, SM4_DECRYPT |
实际项目中,你大概率同时用到这三种算法。比如先SM2加密会话密钥,再用SM4加密业务数据。嗯,这里要注意:gmssl的SM2默认使用16进制字符串作为输入输出,不是字节流,设计时别搞混了。
SM2密钥生成示例
直接上代码。咱们生成一对SM2密钥,然后看看私钥、公钥长什么样。
from gmssl import sm2
# 创建一个SM2密钥对象
sm2_key = sm2.SM2Key()
# 生成密钥对
private_key_hex = sm2_key.generate_private_key()
public_key_hex = sm2_key.generate_public_key(private_key_hex)
print("私钥(hex):", private_key_hex)
print("公钥(hex):", public_key_hex)
# 验证:用私钥签名,用公钥验签
data = "hello gmssl".encode()
random_hex = "1234567890abcdef1234567890abcdef"
sign_hex = sm2_key.sign(data, private_key_hex, random_hex)
print("签名:", sign_hex)
verify_ok = sm2_key.verify(sign_hex, data, public_key_hex)
print("验签结果:", verify_ok)
注意random_hex这个参数:它其实是SM2签名算法要求的随机数k。我曾在项目里随手写了个固定值,结果每次签名都一样,差点被攻击方利用。这个k必须每次随机生成,最好用系统安全的随机数源。
生成的私钥是一串64字符的十六进制数(32字节),公钥是130字符(65字节,含04前缀)。你可以直接存文件,或者转成PEM格式。gmssl也提供了export_key方法,但我习惯自己封装,方便兼容其他库。
SM2密钥生成流程图
下面这张图展示了密钥生成的完整流程,你可以对照代码理解每个步骤的作用。
避坑指南:我踩过的几个坑
- Python版本问题:gmssl要求Python 3.6+,我曾在CentOS自带2.7上装了半天才发现不支持。建议直接用Python 3.8~3.10。
- 密钥长度:SM2私钥固定32字节,公钥65字节(含04)。如果你从其他系统拿到压缩公钥(33字节),需要先解压才能导入gmssl。我写过一段解压函数,有兴趣可以留言。
- 随机数重用:前面提到的签名随机数必须唯一。如果你用多线程生成签名,小心竞争条件导致重复随机数。最好用
secrets._hex(32)替代自己写的随机数。 - 编码问题:gmssl默认输入输出是hex字符串。如果你拿到的是base64格式,记得先转成hex再传参。我在对接某第三方接口时,对方发来的公钥是base64编码,没转换直接传进去,结果验签一直失败……
小结
gmssl的安装和基本使用就这么简单。你可以试试把生成的密钥对存成PEM文件,或者用SM2加密一段小数据。下个章节咱们会深入SM2的加密解密接口,到时候代码量会多一些,但原理是一样的。先把这个基础打牢。
- 安装:
pip install gmssl - 密钥生成:
SM2Key().generate_private_key()+.generate_public_key() - 私钥32字节hex,公钥130字符hex(含04)
- 签名签名随机数必须每次不同