经常看到很多项目用到了Crypto模块,但是我在python上试了各种办法,就是装不上去。后来发现这玩意儿停更很多年了。
它的替代品是 pycrytodome
所以,实际上安装这个即可:
pip install pycryptodome -i https://mirrors.aliyun.com/pypi/simple/
下面是长文本加密的demo
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File : longRsa.py
# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
# Date : 2020/2/28
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
import base64
'''
单次加密串的长度最大为(key_size/8 - 11)
加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117,
解决办法是 分块 加密,然后分块解密就行了,
因为 证书key固定的情况下,加密出来的串长度是固定的。
Java 中使用的是 PKCS#8 生成的私钥,而Python中常用的是PKCS#1,就导致无法解密,python也是支持PKCS#8的,下面是这两种方式的区别。
pkcs1:
-----BEGIN RSA PUBLIC KEY-----\n{}\n-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----\n{}\n-----BEGIN RSA PRIVATE KEY-----
pkcs8:
-----BEGIN PUBLIC KEY-----\n{}\n-----BEGIN PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----\n{}\n-----BEGIN PRIVATE KEY-----
仔细观察,pkcs1的公钥和私钥开头和结尾都比pkcs8的多了RSA
{"Data":"ajEGp0tiLe3b90VKmPIe7Yf76I+cM7wyiN5rH72XQGRWMSYizmwMWkcPi4QqPXxQfgKZhR5Za7wmqZE5HT0sNWKIFxva5d0I1GURYb/sniPQQYnpumVcew6ZJZajz/oK1zJRrHB0R8EY2Qidd34TYuKB3GWiU8X39fPBW1eHq7VKgG3ArlXre1fWXJ0Tq9d0zNbgRgxiH4LdJoEWJYdwkrKEo/9rmDs7zzM8jPbVg9WszrnRSrwRFkLqmHa9xLC9kynUxM2ao9BxoeTDrLPQX2XyU25iwpHIVC4TvetPK30oIM7dOgGB2cWITHRcQxXnA75mfqVgeCu9CNzrPwk1hQg7HfOW/poMllnGUGK+tTLtclBM8oYmOVXYSN8yOHt3mCFByGt+JC14UlkEojstNGviliI59ZFLVF6D4WzURaVjIh5jj3PvezjCiijLMbrMH5ZYhjyyk31xKnxcn0Yt4b0W6Y2kSUSkyGqjyHc/IGVcjNPWP/vFX7Mfp0+6qUPD"}
{"FBankInfos":[{"FAccountName":"四川中电福溪电力开发有限公司","FBankCode":"123902292987","FOpenBankName":"中行宜宾分行营业部"}],"FCreditCode":"91510000669591631K","FGroup":"0299","FName":"四川中电福溪电力开发有限公司"}
'''
def rsa_long_encrypt(pub_key_str, msg):
msg = msg.encode('utf-8')
length = len(msg)
# default_length = 117
default_length = 100
#公钥加密
pubobj = Cipher_pkcs1_v1_5.new(RSA.importKey(pub_key_str))
#长度不用分段
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 rsa_long_decrypt(priv_key_str, msg):
msg = base64.b64decode(msg)
length = len(msg)
default_length = 128
#私钥解密
priobj = Cipher_pkcs1_v1_5.new(RSA.importKey(priv_key_str))
#长度不用分段
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)
if __name__ == '__main__':
msg = '{"FBankInfos":[{"FAccountName":"中化岩土集团股份有限公司","FBankCode":"11001009000056070231","FOpenBankName":"中国建设银行北京大兴支行"}],"FCreditCode":"91110000710929148A","FGroup":"0299","FName":"中化岩土集团股份有限公司"}'
print(msg)
rsa_dict = {
'PUBLIC_KEY': 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXNJgUbHeMrJCZbfyVAl8+e94FhSqaSweKsEHjVgYBYwCgNrzeQStP8pMrWbahLTfvs552ajUC2vrJFXfS+HmcnJ3Yv6JgCobDoenpz09Bnov2x/B76DxON5EnruAKU/xqqUA/BPVbf7y3qGTuomRXg+KFH3tiezu4kg/Hz4OQeQIDAQAB',
'PRIVATE_KEY': 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJc0mBRsd4yskJlt/JUCXz573gWFKppLB4qwQeNWBgFjAKA2vN5BK0/ykytZtqEtN++znnZqNQLa+skVd9L4eZycndi/omAKhsOh6enPT0Gei/bH8HvoPE43kSeu4ApT/GqpQD8E9Vt/vLeoZO6iZFeD4oUfe2J7O7iSD8fPg5B5AgMBAAECgYApxqs6AVnqcQcmjP/bP6OHBPwrtEY4CQDVbatWnz7bhTn4CgeWtJS96vyEXq4Zy/+HZ64hc2igGFZv1lGb5XDbyqODi5kGaeylB8pXpwdUa1/WRMa60c+2LWWc+piVWoSOsPr0Q1NtnFunsX8/FoRyOrP+QcN8QcJR0SFe0ApgDQJBAMdqGUotVRL3YSAWgRTaFFby2wV/ur0uhycEJ0DZIQyZV0Yk0jmKiUdmRAs9LZGkuL929Zee4O0n1ANjARkkCvsCQQDCHHzsR9CMfaf52orowrCvINqon8iq+5FaKDgsddcRRG9yhdNSGhfTSdNTw82YXlbGB10siEjfH60HxAjJ1rgbAkA0CZ3b24SN1HxF8Vlx5Y7VOb6p6rECWTfvmIfdxkt3jDRYG5e4aEx2k1tCS46uqPuFCzf/fvhXKsOKtrU8qEktAkB7HNJmkc3FrVTCdUexBPpGuNG2LVF6kH/J7MRj/oFfZEZDHnm/EumVirdL414ci4kBpF4GBpIhYde+myjvyw2NAkAYHc8QDgfwKnMFKGMDq4wY+rNf1T5SPmKyM+60A5GmMTo1mu2/gFtNrLomFT2stjQQhtRVIjYtNCGrwlzVG1cC'
}
public_key = f'-----BEGIN PUBLIC KEY-----\n{rsa_dict["PUBLIC_KEY"]}\n-----END PUBLIC KEY-----\n'
private_key = f'-----BEGIN PRIVATE KEY-----\n{rsa_dict["PRIVATE_KEY"]}\n-----END PRIVATE KEY-----\n'
# public_key = '''-----BEGIN PUBLIC KEY-----
# MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCXNJgUbHeMrJCZbfyVAl8+e94FhSqaSweKsEHjVgYBYwCgNrzeQStP8pMrWbahLTfvs552ajUC2vrJFXfS+HmcnJ3Yv6JgCobDoenpz09Bnov2x/B76DxON5EnruAKU/xqqUA/BPVbf7y3qGTuomRXg+KFH3tiezu4kg/Hz4OQeQIDAQAB
# -----END PUBLIC KEY-----
# '''
# private_key = '''-----BEGIN PRIVATE KEY-----
# MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJc0mBRsd4yskJlt/JUCXz573gWFKppLB4qwQeNWBgFjAKA2vN5BK0/ykytZtqEtN++znnZqNQLa+skVd9L4eZycndi/omAKhsOh6enPT0Gei/bH8HvoPE43kSeu4ApT/GqpQD8E9Vt/vLeoZO6iZFeD4oUfe2J7O7iSD8fPg5B5AgMBAAECgYApxqs6AVnqcQcmjP/bP6OHBPwrtEY4CQDVbatWnz7bhTn4CgeWtJS96vyEXq4Zy/+HZ64hc2igGFZv1lGb5XDbyqODi5kGaeylB8pXpwdUa1/WRMa60c+2LWWc+piVWoSOsPr0Q1NtnFunsX8/FoRyOrP+QcN8QcJR0SFe0ApgDQJBAMdqGUotVRL3YSAWgRTaFFby2wV/ur0uhycEJ0DZIQyZV0Yk0jmKiUdmRAs9LZGkuL929Zee4O0n1ANjARkkCvsCQQDCHHzsR9CMfaf52orowrCvINqon8iq+5FaKDgsddcRRG9yhdNSGhfTSdNTw82YXlbGB10siEjfH60HxAjJ1rgbAkA0CZ3b24SN1HxF8Vlx5Y7VOb6p6rECWTfvmIfdxkt3jDRYG5e4aEx2k1tCS46uqPuFCzf/fvhXKsOKtrU8qEktAkB7HNJmkc3FrVTCdUexBPpGuNG2LVF6kH/J7MRj/oFfZEZDHnm/EumVirdL414ci4kBpF4GBpIhYde+myjvyw2NAkAYHc8QDgfwKnMFKGMDq4wY+rNf1T5SPmKyM+60A5GmMTo1mu2/gFtNrLomFT2stjQQhtRVIjYtNCGrwlzVG1cC
# -----END PRIVATE KEY-----
# '''
enmsg = rsa_long_encrypt(public_key, msg).decode('utf-8')
print(enmsg)
demsg = rsa_long_decrypt(private_key, enmsg).decode("utf-8")
print(demsg)