关于国密HmacSM3以及使用Python实现HmacSM3加密的三种方法代码程序

    SM3 是国产的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。相关标准为 GM/T 0004-2012《SM3密码杂凑算法》。类似于我们平常经常接触到的 MD5算法,我们可以认为是 MD5 的国产对应版本。

    在一些政务服务系统中,有要求必须使用国产 SM3 进行加解密处理。SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法是公开的。政务云加密的格式示例如下:

print(b64encode(enc_key).decode('utf-8'))
rbPb15S/Z9t+agffno5wuhB77VbRi6F9Iv2qIxU7WHw=
print(b64encode(mac_key).decode('utf-8'))
G9GtHFE1YluXY1zWPlYk1e/nWfu0WSEb0KRcjhDeP/o=

    但在使用 HmacSM3加密的开发过程中,发现网上虽然有不少 hmacSM3 加密的资料,但我没有找到使用 key 结合 sm3进行加密的。很多都是直接将数据进行 sm3加密,并不能满足我这里调用政务云加密的需要。也因此导致签名 signature一直不成功。

    最终经过多次测试、试验找到了好办法。Python实现 国密 HmacSM3 加密的方法有多种,但也有一些区别。我这里测试通过了3种,总结出此篇文章。

一,使用专门的 gmssl 库。

    先使用 pip install gmssl 安装gmssl python 库,导入后使用其中的 sm3 加密,需要注意的是,国密sm3加密要加密的数据内容要求是 bytes 类型数据。加密后返回 哈希值。

from gmssl import sm3
def fun_sm3_hash(data: str):
    data_list = [i for i in bytes(data.encode('UTF-8'))]
    hash_val = sm3.sm3_hash(data_list)
    return hash_val

data = "hello, linge"
print(fun_sm3_hash(data))

    需要注意,上面的方法未使用到 key, 另外通过以上的方法加密出来的数据是 64 位长的 16进制数据。输出结果为:

a050daf6a9bb9153a32b1f880afbf36aaf88a1fe2ac6437fd5a801793862a610

二,使用通用的 hashlib 库。

    在Python中,常用的第三方库 hashlib 也可以用来实现 SM3 加密。hashlib是Python标准库中的一个模块,提供了常见的哈希算法,其中包括SM3,这就给我们带来了很多的便利,不用专门去安装 gmssl 模块,如果是docker 镜像就不用更新镜像了。代码如下:

# 创建SM3对象,传入数据后已计算 hash 很像 md5的用法。
import hashlib
sm3 = hashlib.new('sm3')
data = "hello, linge"
sm3.update(data.encode('utf-8'))
hash_value = sm3.hexdigest()
print(hash_value)

    需要注意,上面的方法也未使用到 key, 另外通过以上的方法加密出来的数据是 64 位长的 16进制数据。输出结果同上也为:

a050daf6a9bb9153a32b1f880afbf36aaf88a1fe2ac6437fd5a801793862a610

    上面的两种方法我都未找到加入 key 的方法,大家可以到比如 hashlib 官网中去看看:https://docs.python.org/zh-cn/3.13/library/hashlib.html 也许有这样的方法,但我没有找到。如果要加入 key,我这里经过描

三、使用原生的密钥哈希模式 hmac

import hmac
key = b"secret"
data = b"Hello, Linge!"
hmac_value = hmac.new(key, data, digestmod="sm3").hexdigest()
print(hmac_value)

    通过这种方法可以引入key,最后的输出结果为:

17aeae7eb061fe6950df13cf77bd9c22700bd15321b5dfb1710a71d41d5a3ba8

    在一些政务云服务中基本要求这种用法,但在网上我没有看到有这类内容的文章。政务云的处理一般要要进行base64处理。如下过程,最后处理成这样的数据:

import hmac,base64
key = b"secret"
data = b"Hello, Linge!"
#用digest() 输出二进制格式数据 不用 hexdigest()输出16进制数据
hmac_value = hmac.new(key, data, digestmod="sm3").digest()
sign = base64.b64encode(hmac_value)
return sign.decode('utf-8')
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值