python-gnupg解密返回空结果,请求排查代码错误
GPG解密结果为空字符串的问题排查与修复
问题描述
使用以下Python代码生成GPG密钥、加密内容并解密时,解密结果始终为空字符串:
with tempfile.TemporaryDirectory() as tmpdir: gpg = gnupg.GPG(gnupghome=str(tmpdir), verbose=True) gpg.encoding = 'utf-8' input_data = gpg.gen_key_input( key_type='RSA', key_length=2048, name_real='Atfinity', name_comment='Generated by Atfinity', name_email='no-reply@atfinity.ch', passphrase='test', ) key = gpg.gen_key(input_data) content = 'Encrypt this please' encrypted = gpg.encrypt_file( StringIO(content), recipients=key.fingerprint, always_trust=True, passphrase='test', sign=False ) decrypted = gpg.decrypt(str(encrypted), always_trust=True, passphrase='test') self.assertEqual(content, str(decrypted))
问题原因与修复方案
1. 错误使用encrypt_file处理字符串内容
encrypt_file设计用于处理实际文件路径或二进制文件对象,传入文本模式的StringIO可能导致加密内容格式异常。对于字符串内容,直接使用gpg.encrypt()方法更适配,无需额外封装成文件对象。
2. 加密时多余传递passphrase参数
passphrase参数仅在签名操作时用于解锁本地私钥,而你设置了sign=False,加密操作只需要接收方的公钥,完全不需要这个参数。多余的参数可能干扰GPG的正常逻辑流程。
3. 未添加错误排查机制
解密失败时,gnupg对象的status和stderr属性会返回具体失败原因(如密钥不可用、密码错误、加密内容损坏等),添加这些信息的打印能快速定位问题。
修正后的完整代码
import tempfile from io import StringIO import gnupg import unittest class TestGPGEncryptDecrypt(unittest.TestCase): def test_basic_encrypt_decrypt(self): with tempfile.TemporaryDirectory() as tmpdir: # 初始化GPG实例 gpg = gnupg.GPG(gnupghome=str(tmpdir), verbose=True) gpg.encoding = 'utf-8' # 生成带密码的RSA密钥 key_input = gpg.gen_key_input( key_type='RSA', key_length=2048, name_real='Atfinity', name_comment='Generated by Atfinity', name_email='no-reply@atfinity.ch', passphrase='test', ) generated_key = gpg.gen_key(key_input) target_content = 'Encrypt this please' # 使用encrypt方法直接加密字符串 encrypted_result = gpg.encrypt( target_content, recipients=generated_key.fingerprint, always_trust=True, sign=False ) # 先验证加密是否成功 if not encrypted_result.ok: print(f"加密失败状态: {encrypted_result.status}") print(f"加密错误详情: {encrypted_result.stderr}") self.fail("加密流程失败") # 执行解密操作 decrypted_result = gpg.decrypt( str(encrypted_result), always_trust=True, passphrase='test' ) # 打印解密状态用于排查(可选) print(f"解密状态: {decrypted_result.status}") print(f"解密错误详情: {decrypted_result.stderr}") # 断言验证结果 self.assertEqual(target_content, str(decrypted_result)) if __name__ == '__main__': unittest.main()
内容的提问来源于stack exchange,提问作者Thorben Croisé
相关产品推荐
相关产品推荐

