最近一个项目,需要使用sm2非对称加密,对方直接给的秘钥证书,python使用gmssl 进行加密,解密,加签,验签用的秘钥是这种格式
# Private Key秘钥 5aa03412c3051e1d4cf9d19cfbeeec70c28f388c9f82747cc912096c9cd44bea
# Public Key 公钥 044291b381a039a8d7d02d7272d2d7c78a30d33e3eeaa0b509bf77d2376582ab2d573730e6bfe9a53bad53f53ac1a85d9c11050931f04bc8b3afc04144d5a6f9be
但是对方给的是这种格式的秘钥证书,python如何使用呢?
1. openssl提取 privateKey.pfx
秘钥证书秘钥转换为python gmssl库可用秘钥
# 注意openssl提取sm2秘钥证书需要对应版本,我这里是下载的 openssl.1.1.1 因为有的版本是不支持提取sm2秘钥证书的
openssl pkcs12 -in privateKey.pfx -nocerts -out private_key.pem -nodes
# 转为把私钥证书转为private_key.pem格式
openssl ec -in private_key.pem -text -noout
# 查看公私钥
priv = """上面复制私钥"""
pub = """上面复制公钥"""
print('处理后的私钥:{}'.format(priv.replace(":", '').replace('\n', '').replace(' ', '')))
print('处理后的公钥:{}'.format(pub.replace(":", '').replace('\n', '')).replace(' ',''))
# 我这里privateKey.pfx 其实就包含了公私钥信息,就不用单独提取公钥了
2.对方PublicKey.cer文件公钥提取
对方公钥提取就简单了,直接安装下面步骤来
3.python实现 SM2加密
# 这里直接上代码 python解释器版本为3.6 3.10 本人亲测可以运行下面代码 sm2有不同的配置,要看对方使用的sm2进行修改 如 iv mode
import os
import random
import string
import base64
from gmssl import sm4, sm2
# python解释器版本3.6
class SM4(object):
def __init__(self):
self.crypt_sm4 = sm4.CryptSM4()
self.crypt_sm4_iv = base64.b64decode("这里请填写你的iv值")
# sm4 cbc 加密
def encrypt_sm4(self, encrypt_key, value):
"""
国密sm4加密
:param encrypt_key: sm4加密key
:param value: 待加密的字符串
:return: sm4加密后的十六进制值
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(encrypt_key.encode(), sm4.SM4_ENCRYPT)
date_str = str(value)
encrypt_value = crypt_sm4.crypt_cbc(self.crypt_sm4_iv, date_str.encode())
# 返回base64编码的加密数据
return base64.b64encode(encrypt_value).decode()
# sm4 cbc 解密
def decrypt_sm4(self, decrypt_key, encrypt_value):
"""
国密sm4解密
:param decrypt_key:sm4加密key
:param encrypt_value: 待解密的十六进制值
:return: 原字符串
"""
crypt_sm4 = self.crypt_sm4
crypt_sm4.set_key(decrypt_key.encode(), sm4.SM4_DECRYPT) # 设置密钥
decrypt_value = crypt_sm4.crypt_cbc(self.crypt_sm4_iv, encrypt_value) # 开始解密。十六进制类型
return decrypt_value.decode()
# 生成128位随机密钥key
@staticmethod
def generate_key():
"""
生成128位随机密钥key
:return: 128位随机密钥key
"""
return ''.join(random.sample(string.ascii_letters + string.digits, 16))
class SM2(object):
def __init__(self):
self.public_key = '044291b381a039a8d7d02d7272d2d7c78a30d33e3eeaa0b509bf77d2376582ab2d573730e6bfe9a53bad53f53ac1a85d9c11050931f04bc8b3afc04144d5a6f9be'
self.private_key = '5aa03412c3051e1d4cf9d19cfbeeec70c28f388c9f82747cc912096c9cd44bea'
# 对方的公钥
self.others_public_key = ''
# 公钥加密
def encrypt_sm2(self, public_key, data, java=False):
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key='', mode=1, asn1=True)
encrypt_res = sm2_crypt.encrypt(data.encode("UTF_8"))
if java:
encrypt_res = b'\x04' + encrypt_res
return base64.b64encode(encrypt_res).decode("utf-8")
# 私钥签名
def sign_sm2(self, private_key, public_key, data):
sm2_crypt = sm2.CryptSM2(private_key, public_key, mode=1, asn1=True)
random_hex_str = os.urandom(32).hex() # 随机数
signature = sm2_crypt.sign_with_sm3(data.encode("utf-8"), random_hex_str)
return base64.b64encode(bytes.fromhex(signature)).decode('utf-8')
# 公钥验签
def verify_sm2(self, public_key, sign, data):
sm2_crypt = sm2.CryptSM2(private_key=None, public_key=public_key, mode=1, asn1=True)
return sm2_crypt.verify(sign, data)
obj_sm4 = SM4()
obj_sm2 = SM2()
标签:sm2,encrypt,python,crypt,self,sm4,SM2,秘钥,key
From: https://www.cnblogs.com/guokaifeng/p/18410813