Python3.6.1 RSA 公钥pubkey分段加密

前段时间,遇到有接口是使用rsa公钥加密方法实现的,于是需要编写rsa 加密的脚本。其中 ,公钥(publickey)是已知的。不同长度的字段使用RSA加密出来的长度不一样。
加密的字段长短规则如下:
加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117,
那么对于 2048bit的证书,被加密的长度最长2048/8 - 11 =245,
解决办法是 分块 加密,然后分块解密就行了,
因为 证书key固定的情况下,加密出来的串长度是固定的。
也就是说,如果使用2048bit的证书,并且被加密的字符段是小于245个,那么被加密出来的字符长度是344个,以此类推,被加密的字符串可以是688个,1032个等。
以下是针对某个接口的传参使用rsa加密技术后,对该接口进行的测试,脚本如下:

#coding=utf-8 import re import json from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.PublicKey import RSA import base64 import requests from base64 import b64encode, b64decode import rsa#单次加密串的长度最大为 (key_size/8)-11 ''' 加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117, 那么对于 2048bit的证书,被加密的长度最长2048/8 - 11 =245, 解决办法是 分块 加密,然后分块解密就行了, 因为 证书key固定的情况下,加密出来的串长度是固定的。 ''' def rsa_encrypt(msg,pubkey): pub_title=pubkey pubkey_str="""-----BEGIN PUBLIC KEY-----""" + '\n' + pub_title + '\n' + """-----END PUBLIC KEY-----""" msg = msg.encode(encoding="utf-8") length = len(msg) default_length = 245 # 公钥加密 pubobj = Cipher_pkcs1_v1_5.new(RSA.importKey(pubkey_str)) # 长度不用分段 if length < default_length: encry_text = base64.b64encode(pubobj.encrypt(msg))# 通过生成的对象加密message明 # 对传递进来的用户名或密码字符串 encry_value = https://www.it610.com/article/encry_text.decode('utf8') return encry_value # 需要分段 offset = 0 res = [] while length - offset > 0: if length - offset > default_length: res.append(base64.b64encode(pubobj.encrypt(msg[offset:offset + default_length])).decode("utf-8")) else: res.append(base64.b64encode(pubobj.encrypt(msg[offset:])).decode("utf-8")) offset += default_length return "".join(res)if __name__ == '__main__': pubkey='MIIBIjANBgkqeriG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxq+EkcWV+gB/B81dqK+WJM1/0qgCS0uFodLv/uygtNTKf4mbHwfy/90SPILkpqkO31F3B5MYyLkl9MQFuA9DD95fcFOQFL7wEUnAtnGbzRbVCqo2JcUpyWV79LDeFlsL87NMvwtIGf5geEDLLPT7WS63X6o3LAaWrro3Z/rzf6zwKSWnzoMhjcrV6inwwkLGpOMQxwOgteaLmYvJ8x3BayokTGRDOH2JMMw49C9c5S2mwJ+axkAdi0ei83Y5K5WcCEbxeNaxZiDZs9HN428/QJtOtcXPtp0PyUH3449ycwBjYF+HHjxihvs/PzI/agPWVtE4hGba1Ldya5JMGh7KKQIDAQAB' login_url = 'http://xx.yy.zz.com/api/user/type' login_data = https://www.it610.com/article/{"loginName": "hi@qq.com", "password": "1234test", "loginType": "email", "key": "123445678dfghj"} headers_1 = {'Referer': 'http://xx.yy.zz.com', 'Content-Type': 'application/json'} r = requests.post(url=login_url, data=https://www.it610.com/article/json.dumps(login_data), headers=headers_1) json_data = json.loads(r.text) #print("登录的结果返回值是:\n", json_data) token = json_data['data']['token'] #print("登录的token是:\n", token) headers_2 = {'Referer': 'http://xx.yy.zz.com', 'Content-Type': 'application/json', 'x-Api-token': token} msg='{"newPwd": "1234abcd", "origin": "abcd1234", "verified": "1234abcd"}' print("未加密前的接口数据是:\n",msg) test_data=https://www.it610.com/article/rsa_encrypt(msg,pubkey) print("接口测试传参结果是:\n",test_data) test_url_pwd='http://xx.yy.zz.com/api/user/pwd/modify' test_r=requests.post(url=test_url_pwd,data=https://www.it610.com/article/test_data,headers=headers_2) test_json_data=json.loads(test_r.text) print("接口测试结果是:\n",test_json_data)

运行出来结果如下:
未加密前的接口数据是: {"newPwd": "1234abcd", "origin": "abcd1234", "verified": "1234abcd"} 接口测试传参结果是: OLMy+O4To088reveyvIv3efWTG164BQvjWivZTTeBalEHbqbZ/3kWGXqpZPDrm8+N4+8utk13/wxiipmiPny5xBxbI+CuVssv+gN8owbsqJTlLDgRb0ZhpWbF83cUDVp9/O11epZKXslhsSjINqxRKLqKMYqXd9tZK37KKxbhiZjEu6RVlyUkrri3i1jGJO/e4bmeHIv/XnrEV3J5g2MMv0HvmzKBfpRaGuTYpjAE64u1X7djRxApP+XA/wqSjf13ggPB4hxAmdnV/beNSyg77NVK6gDPvVi7X4zhZ6mjqoZSmA2if/QD5zL8izfHfi7YRqgVW/Kp74URZMzW0HuAA== 接口测试结果是: {'code': 'm00000', 'result': True}

注意:对于指定的pubkey唯一,每次被加密的字符串唯一,但是使用RSA 加密后出来的字符串都是不同的,因为 Cipher_pkcs1_v1_5.new(RSA.importKey(pubkey_str))获取得到的值是随机的,只要满足解密出来的字符串是被加密前的字符串即可。
参考:
http://blog.csdn.net/orangleliu/article/details/72964948
【Python3.6.1 RSA 公钥pubkey分段加密】更多交流,可以加好友
Python3.6.1 RSA 公钥pubkey分段加密
文章图片

    推荐阅读