RSA算法一次能加密的名文长度与密钥长度成正比,如RSA 1024实际可加密的明文长度最大是1024bits。如果大于这个长度怎么办?分段加密:将需要加密的数据按照较小的片段进行切割,然后对每个片段单独进行加密操作。在接收方再将这些加密结果合并起来得到完整的加密结果。这样就能够绕开RSA算法的最大加密长度限制。
长文本RSA加密代码如下:
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import base64
class Encryption(object):
def __init__(self):
# 伪随机数生成器
self.random_generator = Random.new().read
def getKey(self):
# rsa算法生成实例
rsa = RSA.generate(1024, self.random_generator)
# master的秘钥对的生成
private_pem = rsa.exportKey()
public_pem = rsa.publickey().exportKey()
key={}
key["private"] = private_pem
key["public"] = public_pem
with open("./rsa.public.pem", mode="wb") as f:
f.write(public_pem)
with open("./rsa.private.pem", mode="wb") as f:
f.write(private_pem)
return key
def rsa_long_encrypt(self, msg, pub_key_str, length=100):
"""
单次加密串的长度最大为 (key_size/8)-11
1024bit的证书用100, 2048bit的证书用 200
"""
pubobj = RSA.importKey(pub_key_str)
pubobj = Cipher_pkcs1_v1_5.new(pubobj)
res = []
for i in range(0, len(msg), length):
print(msg[i:i + length])
res.append(
str(
base64.b64encode(pubobj.encrypt(
msg[i:i + length].encode(encoding="utf-8"))), 'utf-8'
)
)
for r in res:
print(len(r))
return "".join(res)
def rsa_long_decrypt(self, msg, priv_key_str, length=172):
"""
1024bit的证书用128,2048bit证书用256位
"""
privobj = RSA.importKey(priv_key_str)
privobj = Cipher_pkcs1_v1_5.new(privobj)
res = []
for i in range(0, len(msg), length):
res.append(
str(
privobj.decrypt(
base64.b64decode(msg[i:i + length])
, 'xyz'), 'utf-8'
)
)
print(res)
return "".join(res)
if __name__ == '__main__':
str1="""{"ans": [{"id": 5, "sno": "6", "name": "121", "brithday": "1234-01-02", "sex": "1", "tel": "2"}, {"id": 9, "sno": "99, "name": "121", "brithday": "1234-01-02", "sex": "1", "tel": "2"}"""*5
a = Encryption()
key = a.getKey()
# with open("rsa.public.pem", mode="r") as f:
# pubkey = f.read()
# cipher_text = a.rsa_long_encrypt(str1, pubkey)
# print(cipher_text)
# with open("rsa.private.pem", mode="r") as f:
# prikey = f.read()
# plaintext = a.rsa_long_decrypt(cipher_text, prikey)
# print(plaintext)