python通过gmssl进行SM2国密算法签名实战踩坑

现在国密算法用的是越来越多,之前JAVA采用hutool工具包进行签名,还算顺利,但是最近想把功能切到python中,困扰了我大半年时间,终于得到解决。

其实官方的例子没有问题,如下:

1. 初始化CryptSM2

import base64
import binascii
from gmssl import sm2, func
#16进制的公钥和私钥
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
sm2_crypt = sm2.CryptSM2(
    public_key=public_key, private_key=private_key)

2. sign_with_sm3

data = b"111" # bytes类型
sign = sm2_crypt.sign_with_sm3(data) #  16进制

问题:

1、之前做Java的时候,签名只需要设置私钥,公钥设置为空,所以我使用gmssl进行签名,也想当然的把公钥设置''(其实gmssl不允许public_key设置为None,就应该想到),导致签名的值一直无法验签。所以再次强调,gmssl签名一定要设置公钥

2、gmssl获取公钥时,有个小bug

self.public_key = public_key.lstrip("04") if public_key.startswith("04") else public_key

如果公钥类似于0449A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207,那么会把前面的044都给去掉了,所以如果公钥时04开头的话,就自己写代码把04去掉。

同时参数需要注意一下:

1、mode

我看源码中写的注释为:mode: 0-C1C2C3, 1-C1C3C2 (default is 1)

好像错了,实际上应该是0-C1C3C2,默认也是0

Java中的设置为sm2.setMode(SM2Engine.Mode.C1C3C2);

2、asn1

asn1=False是明文形式

Java的设置为sm2.usePlainEncoding()

把自己趟过的坑记录下来,同时也希望能对使用国密的开发人员有所帮助。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值