记第一次接触RSA加密----python

记python使用支付宝RSA生成秘钥工具遇到的问题


报错 AttributeError: ‘str’ object has no attribute ’

我在和第三方对接接口时,第三方要求使用支付宝rsa秘钥工具来生成公钥和私钥(由于第一次接触,都不太懂)我需要对我请求他时带的参数需要进行签名,和对他的签名进行验证,但是中间一直出现VerificationError: Verification failed 验证错误,因为我使用的阿里的SDK进行的验签和加签,所以怀疑是因为没有使用对SDK使用正确,我问第三方他们有没有使用阿里的SDK,他说只用秘钥生成公钥和私钥没有使用, 于是我用python rsa模块进行加签和验签,在加签时出现了这个错误

后来经过一系列搜索,因为阿里生成的是是单纯的str需要转换成公钥对象和私钥对象, 举个栗子:

In [4]: pubkey
Out[4]: PublicKey(11690135687533933382360195974198542320855561302916716673520411392050566078072206589551125140476896542230602422113630896040254008411359287782630915870990731, 65537)

In [5]: privkey
Out[5]: PrivateKey(11690135687533933382360195974198542320855561302916716673520411392050566078072206589551125140476896542230602422113630896040254008411359287782630915870990731, 65537, 1942320940866335056540887955857728112849172330553124614461506624472261683428563987435789823643183600581268208466749887437038591129786226046998711491544681, 7096194277812885680822727267687878129579066157151458337565184598926324047667321479, 1647381008730914280393162847196573429038377988150536898752334551643712989)

然后我就查看SDK源码因为源码是可以生成签名

def sign_with_rsa2(private_key, sign_content, charset):
    if PYTHON_VERSION_3:  # 判断是否是python3,我是python2这个不用管
        sign_content = sign_content.encode(charset)
    private_key = fill_private_key_marker(private_key) # 对私钥进行标记,没有标记在下方format='PEM'会报错
    signature = rsa.sign(sign_content,
                         priv_key=rsa.PrivateKey.load_pkcs1(private_key, format='PEM'),
                         hash='SHA-256') # 对内容加签
    sign = base64.b64encode(signature) # 对签名进行编码
    if PYTHON_VERSION_3:
        sign = str(sign, encoding=charset)
    return sign

所以需要像sdk一样将对私钥进行标记

但是…验签的时候还是会报错验签错误
于是

def verify_with_rsa(public_key, message, sign):
    public_key = fill_public_key_marker(public_key) # 对公钥进行标记
    sign = base64.b64decode(sign) # 对签名进行64位解码
    return rsa.verify(message, sign,
                      rsa.PublicKey.load_pkcs1_openssl_pem(public_key)) # 进行验证

于是我调用这个方法但是发现依然验证错误,将这代码单独取出来却可以了,但是本地测试没有,获取请求数据再验证又回出现验证错误, 我打印了两次数据的区别由于python2的编码默认unicode,所以一个本地测试时数据编码是utf-8,但是获取到的是unicode

但是数据都在字典中, 例
d = {u'aa': u'aa', u'bb', u'bb'}
需要将字典内的数据转换为
d = {'aa': 'aa', 'bb': 'bb'}

所以:

import json
d = {u'aa': u'aa', u'bb', u'bb'}
d = eval(json.dumps(d).encode('utf-8'))
>>> d
>{'aa': 'aa', 'bb': 'bb'}

最后

>>> rsa.verify(sign_content, sign, rsa.PublicKey.load_pkcs1_openssl_pem(public_key))
> True

猜你喜欢

转载自blog.csdn.net/qq_19461647/article/details/82737182