Python | Python 实现RSA加解密 验签 无 长度限制 加密解密, 分段加密

迷南。 2022-10-02 01:54 476阅读 0赞

系列文章目录

Python | Flask 解决跨域问题


文章目录

  • 系列文章目录
  • 为什么要分段加密
  • 代码示例
  • 测试
  • 测试结果

为什么要分段加密

加密的字段长短规则如下:

加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117,

那么对于 2048bit的证书,被加密的长度最长2048/8 - 11 =245,

解决办法是 分块 加密,然后分块解密就行了,
因为 证书key固定的情况下,加密出来的串长度是固定的。
也就是说,如果使用2048bit的证书,并且被加密的字符段是小于245个,那么被加密出来的字符长度是344个,以此类推,被加密的字符串可以是688个,1032个等。

代码示例

  1. from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
  2. from Crypto.Signature import PKCS1_v1_5
  3. from Crypto.PublicKey import RSA
  4. from Crypto.Hash import SHA256
  5. import base64
  6. class RsaUtil:
  7. def __init__(self, pub_key, pri_key):
  8. self.pri_key_obj = None
  9. self.pub_key_obj = None
  10. self.verifier = None
  11. self.signer = None
  12. if pub_key:
  13. pub_key = RSA.importKey(base64.b64decode(pub_key))
  14. self.pub_key_obj = Cipher_pkcs1_v1_5.new(pub_key)
  15. self.verifier = PKCS1_v1_5.new(pub_key)
  16. if pri_key:
  17. pri_key = RSA.importKey(base64.b64decode(pri_key))
  18. self.pri_key_obj = Cipher_pkcs1_v1_5.new(pri_key)
  19. self.signer = PKCS1_v1_5.new(pri_key)
  20. def public_long_encrypt(self, data, charset='utf-8'):
  21. data = data.encode(charset)
  22. length = len(data)
  23. default_length = 117
  24. res = []
  25. for i in range(0, length, default_length):
  26. res.append(self.pub_key_obj.encrypt(data[i:i + default_length]))
  27. byte_data = b''.join(res)
  28. return base64.b64encode(byte_data)
  29. def private_long_decrypt(self, data, sentinel=b'decrypt error'):
  30. data = base64.b64decode(data)
  31. length = len(data)
  32. default_length = 128
  33. res = []
  34. for i in range(0, length, default_length):
  35. res.append(self.pri_key_obj.decrypt(data[i:i + default_length], sentinel))
  36. return str(b''.join(res), encoding = "utf-8")
  37. def sign(self, data, charset='utf-8'):
  38. h = SHA256.new(data.encode(charset))
  39. signature = self.signer.sign(h)
  40. return base64.b64encode(signature)
  41. def verify(self, data, sign, charset='utf-8'):
  42. h = SHA256.new(data.encode(charset))
  43. return self.verifier.verify(h, base64.b64decode(sign))

测试

  1. from rsa_util import RsaUtil
  2. data = "{\"0\":\"0\",\"1\":\"1\",\"10\":\"10\",\"11\":\"11\",\"12\":\"12\",\"13\":\"13\",\"14\":\"14\",\"15\":\"15\",\"16\":\"16\",\"17\":\"17\",\"18\":\"18\",\"19\":\"19\",\"2\":\"2\",\"3\":\"3\",\"4\":\"4\",\"5\":\"5\",\"6\":\"6\",\"7\":\"7\",\"8\":\"8\",\"9\":\"9\"}"
  3. pub_key = ''' MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQFA4YVQZatJAyO7TsuzkWE8dz 17qi8GuOCnegKbKd6alLXkDzKhVG3kd3GijouHtlqsm2zFCK7K+I5MUu8Fuk23OE wIVZn9StltjLzJ1hB1AZC1/NCoCFZG5T2+AaQolrw8LvPS5jH2TuYQf7oLDHR88B KJgV/tZlr22Jicqm0wIDAQAB '''
  4. pri_key = ''' MIICWwIBAAKBgQCQFA4YVQZatJAyO7TsuzkWE8dz17qi8GuOCnegKbKd6alLXkDz KhVG3kd3GijouHtlqsm2zFCK7K+I5MUu8Fuk23OEwIVZn9StltjLzJ1hB1AZC1/N CoCFZG5T2+AaQolrw8LvPS5jH2TuYQf7oLDHR88BKJgV/tZlr22Jicqm0wIDAQAB AoGAMP6A5IlVRdcNCef/2Fi6SuWi96OuleYHzR+GGnLTiJuCtFxy3b27yoOf7cJ5 ktnZLHNtcLn90aA2+OhCnXmiz+M9PNArzfvtDoAKMlM9UEpBjGW/QYPkcHgnKOs9 utAr4OnPB9PFdvCuwya4P8AL/7kpjSW+4zQpUT459BlJFxECQQDYUnQQgyR3CZiG Pj9vPfmmFmogpZpJTG9zAuOjOCxa5BQvV4iKhk6pkQAaVsjc7WMobEIhLqXn/I8E ldsqIPj1AkEAqoFZULpjke8CQm0rmr2UdbhU74KKYzeS2KKKc/2TdQUzTqvBdY2+ VCyc0Ok6BWctBHfsu4FR6YpDYsg3QwvjpwJAEHeuaDdjhkBPwSBp+dDw+UjJiXSx 2xSbg1jb9WfoUH7+XmA+f7UbteLY7ChhIBheLQyYuCfx70gVpxa1WW6rJQJAEahR mpWi6CMLZduub1kAvew4B5HKSRohQAQdOIPjOHQwaw5Ie6cRNeBk4RG2K4cS12qf /o8W74udDObVKkFZ8wJAPL8bRWv0IWTlvwM14mKxcVf1qCuhkT8GgrG/YP/8fcW8 SiT+DifcA7BVOgQjgbTchSfaA+YNe7A9qiVmA+G4GQ== '''
  5. rsa_util = RsaUtil(pub_key, pri_key)
  6. print(f'原文: {data}')
  7. encrypt = rsa_util.public_long_encrypt(data)
  8. print(f'加密: {encrypt}')
  9. decrypt_str = rsa_util.private_long_decrypt(encrypt)
  10. print(f'解密: {decrypt_str}')
  11. sign = rsa_util.sign(data)
  12. print(f'sign: {sign}')
  13. verify = rsa_util.verify(decrypt_str, sign)
  14. print(f'verify: {verify}')

测试结果

  1. 原文: { "0":"0","1":"1","10":"10","11":"11","12":"12","13":"13","14":"14","15":"15","16":"16","17":"17","18":"18","19":"19","2":"2","3":"3","4":"4","5":"5","6":"6","7":"7","8":"8","9":"9"}
  2. 加密: b'BXzccjfWEyF061Beh+bhqi0P88jMeB3eI84/mKgNVrVQFIh6wa209xzQLRCfoVJPN16T1T8jtORisdLXFTmdgH2cXHiorIJfYo+y64aJ8jg1hGe2zmUfFws2WcKttTGluhI8x3xbO2wZi1aHS8k8uxUR0bAWu+LHWcBABqGD3DUQf0AJ/graML1G1hIVYVd0JG6+wZnnB5o6wLrViAh7T2TiVtRVzA4dZ+z73mibDzSohHXA5zDb1XAO0RgATBnpMda0krMgZPOVZHhBRlz6PvUcYcv1+kUTsE/bqTDXOPiQJ2H7bnvTAA2ApoM5CRYFAuhKs5FHSHXhOc6K1uOHpQ=='
  3. 解密: { "0":"0","1":"1","10":"10","11":"11","12":"12","13":"13","14":"14","15":"15","16":"16","17":"17","18":"18","19":"19","2":"2","3":"3","4":"4","5":"5","6":"6","7":"7","8":"8","9":"9"}
  4. sign: b'Ho2uhOjKx4GRXulOq/x/owEB01rzztc7WmxTDxjxUzDf7U1cNsp1R7+ahwQuUnGR+lL8RX8G9PxYW/aofc0ApFqIanzEhxbVMsVk87V4M+a/ZEXOJuAgw/0U8IauuMtHl+zaI0KY+TDgrx1rXq5razqU2sU0Ps+y+ILytEK723k='
  5. verify: True

红色图片

发表评论

表情:
评论列表 (有 0 条评论,476人围观)

还没有评论,来说两句吧...

相关阅读

    相关 加密解密 签名

    几个基本概念: 加密:发送方利用接收方的公钥对要发送的明文进行加密。 解密:接受方利用自己的私钥进行解密。 公钥和私钥配对的,用公钥加密的文件,只有对应的私钥才能解密。当