python中rsa非对称算法(包含分段加解密分析)
作者:互联网
import base64 from Crypto import Random from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 from Crypto.PublicKey import RSA class RsaCode: def encrypt(self, msg): msg = msg.encode('utf-8') rsakey = RSA.importKey(self.rsa_public_key) cipher = Cipher_pkcs1_v1_5.new(rsakey) cipher_text = base64.b64encode(cipher.encrypt(msg)) return cipher_text def decrypt(self, cipher_text): rsakey = RSA.importKey(self.rsa_private_key) cipher = Cipher_pkcs1_v1_5.new(rsakey) random_generator = Random.new().read text = cipher.decrypt(base64.b64decode(cipher_text), random_generator) return text.decode('utf8') def long_encrypt(self, msg): msg = msg.encode('utf-8') length = len(msg) default_length = 117 # 公钥加密 rsa_public_key = open('conf/public.pem').read() pubobj = Cipher_pkcs1_v1_5.new(RSA.importKey(rsa_public_key)) # 长度不用分段 if length < default_length: return base64.b64encode(pubobj.encrypt(msg)) # 需要分段 offset = 0 res = [] while length - offset > 0: if length - offset > default_length: res.append(pubobj.encrypt(msg[offset:offset + default_length])) else: res.append(pubobj.encrypt(msg[offset:])) offset += default_length byte_data = b''.join(res) return base64.b64encode(byte_data) def long_decrypt(self, msg): msg = base64.b64decode(msg) length = len(msg) default_length = 128 # 私钥解密 rsa_private_key = open('conf/private.pem').read() priobj = Cipher_pkcs1_v1_5.new(RSA.importKey(rsa_private_key)) # 长度不用分段 if length < default_length: return b''.join(priobj.decrypt(msg, b'xyz')) # 需要分段 offset = 0 res = [] while length - offset > 0: if length - offset > default_length: res.append(priobj.decrypt(msg[offset:offset + default_length], b'xyz')) else: res.append(priobj.decrypt(msg[offset:], b'xyz')) offset += default_length return b''.join(res).decode('utf8') message = '''{"userId":"2088002933729603","transLongitude":"55.755831","transLatitude":"37.617673","merNo":"M000178103","terminalNo":"mini202007030908154720106107","terminalLongitude":"65.755831","terminalLatitude":"77.617673","createTime":"1514561699","tradeType":"WX","orderId":"202207102377965187OR012471381501"}''' test = RsaCode() res_en = test.long_encrypt(message) print('res_en', res_en) res_de = test.long_decrypt(res_en) print('res_de', res_de) res_ren = 'sFXiDF+vDIKoIcOg/h9awIqYi0bOHAMXgmeYH4SBKolNXXUuYJAZhJpOh1MvIDxddxE5vvnHF9wUHbMPSB6wLfh+q+u5r6yBY1a5WP3mGETCxRDxThSxhAzKWzuSL2cwK3Teqz6cfL3qfXIEZp6s4iUeKv4HbBbGaVwyoLcrbfKCbBjNb+e4B3xHqesoab89icPT03N8KTqOll44gTMAMhiB13ABmp0EzEVu0ZYsqET73vyhh2hyPQQVb8ap9cKyiilNHVU42I4ET+5mBL31yOZOpC34ESIHcQKKgFhAndsHlUCwavRdZyobanTuYI7Pn0fEBnNqF5wdpVAp8evie82Lu0E52bmok8Ys3mty91yLvHmWkro7yqQz7iSVf40/QaB5Qjyu7jwucJGlBvF+Pc2/cgLvlocks7y+dE72wwEmWx3GgZBNS7OeQl6a34/OU0Uv34klxe94T8+c6/Q7roXSzTS3W6/EZjefIryWc+DUAqjkQYwhWo+ObT88Zq2X' res_den = test.long_decrypt(res_ren) print('res_den', res_den)
生产公钥私钥的脚本方法
from Crypto import Random from Crypto.PublicKey import RSA # 伪随机数生成器 random_gen = Random.new().read # 生成秘钥对实例对象:1024是秘钥的长度 rsa = RSA.generate(1024, random_gen) # 获取公钥,保存到文件 private_pem = rsa.exportKey() with open('conf/private.pem', 'wb') as f: f.write(private_pem) # 获取私钥保存到文件 public_pem = rsa.publickey().exportKey() with open('conf/public.pem', 'wb') as f: f.write(public_pem)
总结
1)加密使用的是公钥对数据进行加密,而且当你使用一把1024bit的rsa公钥的时候,你一次只能加密最多117byte的数据:
单次加密串的长度最大为(key_size/8 - 11)
即加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117。
至于key的个数,是通过监测Crypto模块中计算key位数的代码来查看的,print(len(key))来查看key的位数这种方式得到的结果是错误的。
2)加密之后进行的字符串拼接:
不可以用byte类型进行拼接,其实''.join(res)是将列表中的各个字符串元素拼接成一个字符串,但是这里加密后
返回的结果类型是byte类型的,不是str,所以才报错了。解决方法就是做bytes拼接,在''.join(res)前加b就可以了,修改
后的为b''.join(res)【此处b 指的是bytes类型】。
3)关于解密:
decrypt方法,这个方法有两个参数,第一个参数是解密的内容,第二个参数是解密错误后返回的结果,这个结
果也需要转换成byte类型。
4)关于公钥私钥:
建议一定使用自动生成的.pem文件,避免读取产生问题。
标签:python,res,加解密,rsa,length,key,offset,msg 来源: https://www.cnblogs.com/MrYang-11-GetKnow/p/16476660.html