PyCryptodome解密函数持续返回错误的原因排查与错误日志记录方法求助
PKCS1_v1_5解密失败的原因及错误捕获方案
先梳理下你遇到的PKCS1_v1_5.decrypt返回哨兵值的常见原因,再说说如何捕获实际错误信息:
一、解密失败的常见原因
- 密钥不匹配:你使用的私钥
fkey.key和加密端的公钥不是配对密钥对,这是最常见的问题,就像你最后排查到的——对方未通知就更改了凭证,大概率就是密钥被替换了。 - 密文处理冗余错误:你代码里用
ast.literal_eval(str(ciphertext))处理密文的步骤完全多余,甚至可能破坏原始字节数据(比如包含特殊控制字符的字节串转字符串后再eval,可能出现意外转换),直接使用b64decode后的原始ciphertext即可。 - 密文损坏/格式错误:虽然你确认传入的是字节串,但base64解码后的密文可能被篡改、截断,或者加密端的编码/填充逻辑和你本地不一致。
- PKCS#1 v1.5填充验证失败:如果加密时的填充不符合标准,或者密文在传输过程中被篡改,解密时填充验证不通过就会触发哨兵值返回。
二、捕获实际解密错误信息的方法
默认情况下PKCS1_v1_5.decrypt会返回你指定的哨兵值,但如果将哨兵值设为None,解密失败时就会抛出ValueError,这样你就能捕获到具体的错误信息。同时记得去掉多余的ast.literal_eval步骤,修改后的代码如下:
from base64 import b64encode, b64decode from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 def decrypt(base64_ciphertext): private_key = RSA.import_key(open('fkey.key').read()) ciphertext = b64decode(base64_ciphertext) cipher_rsa = PKCS1_v1_5.new(private_key) try: # 哨兵值设为None,解密失败会抛出ValueError data = cipher_rsa.decrypt(ciphertext, None) except ValueError as e: # 这里可以记录错误日志,或者返回具体错误信息 print(f"解密失败详情:{str(e)}") # 可以选择抛出异常让上层处理,或者返回错误标识 raise return data
另外注意:你原来的代码里没有导入ast模块,如果实际运行时没报错,说明你本地代码里加了,但这个步骤真的没必要,直接用ciphertext就能正常解密。
补充说明
你最后排查出是对方更改了凭证,这正好对应了最常见的密钥不匹配问题,更换为对方新提供的对应私钥后,解密应该就能正常工作了。
内容的提问来源于stack exchange,提问作者tomoya sensei
相关产品推荐
相关产品推荐

