如何将使用RSA.importKey().decrypt()的Python2代码迁移至Python3?
Python3迁移RSA无填充解密空字节串问题解决
问题背景
原有Python2.7代码可通过RSA私钥解密Base64编码文件,但迁移到Python3后,解密结果为空字节串b''。OpenSSL使用-raw参数(无PKCS填充)可正常解密,私钥为带密码保护的RSA格式。
问题原因
- 文本模式读取文件:Python3中文本模式
open()会自动处理换行符,可能导致Base64字符串混入多余字符,解码后密文无效; - Passphrase类型不匹配:Python3中PyCryptodome要求加密私钥的解密密码为
bytes类型,传入str会导致密钥导入异常; - 错误使用填充解密逻辑:误用
PKCS1_v1_5填充解密器,而实际数据为无填充的原始RSA加密,填充验证失败后返回空值。
解决方案
1. 依赖准备
确保安装Python3兼容的加密库(PyCryptodome替代停止维护的PyCrypto):
pip install pycryptodome
2. 修正后的Python3代码
from Crypto.PublicKey import RSA import base64 def _unlock_keys(self, passphrase): master_key_path = 'master.pem' # 二进制模式读取私钥,密码转bytes类型 with open(master_key_path, 'rb') as f: # 若passphrase是字符串,需编码为bytes(示例用UTF-8) master_key = RSA.importKey(f.read(), passphrase.encode('utf-8')) # 二进制模式读取加密文件,避免文本模式的换行符干扰 with open('host_keys/part.A', 'rb') as f: enc_bits = f.read() # 直接调用RSA密钥的decrypt方法,默认无填充(匹配OpenSSL -raw参数) self.part_A = master_key.decrypt(base64.b64decode(enc_bits)) print(self.part_A)
关键说明
- 二进制文件读取:用
rb模式读取私钥和加密文件,避免文本模式的编码/换行符转换问题,确保Base64解码后的密文完整; - Passphrase类型转换:Python3中PyCryptodome对加密私钥的解密密码要求为
bytes,必须将字符串密码编码为字节类型; - 原始RSA解密:直接调用
master_key.decrypt(),默认使用无填充的原始RSA解密逻辑,与Python2代码及OpenSSL-raw参数行为一致,无需额外使用PKCS填充解密器。
验证建议
若仍有问题,可检查base64.b64decode(enc_bits)后的字节长度是否与RSA密钥模长匹配(如2048位密钥对应256字节密文),长度不匹配则说明读取的Base64字符串存在异常,优先排查文件读取模式问题。
内容的提问来源于stack exchange,提问作者KJ7LNW
相关产品推荐
相关产品推荐

