Python-GNUPG加密文件无法用私钥解密
Python-GNUPG encrypted file cannot be decrypted with private key
我正在尝试使用 python-gnupg 和客户端提供的 public 密钥在 Python 3.6 中加密文本文件,他们有私钥用它解密。我无权访问该密钥。尽管 python-gnupg 出现 成功加密文件(尽管日志中出现一些令人困惑的错误),客户端无法解密它。我们被告知他们得到的错误是 gpg: decryption failed: No secret key
当我们测试使用 Cryptophane(不同的计算机,运行 Windows 而不是 Ubuntu)和相同的 public 密钥加密文件时,他们能够解密它。这就是几个月来手动成功加密的方式。当使用 我们的 公司 public 密钥测试相同的代码时,我们能够使用我们的私钥和 Cryptophane 对其进行解密。
我在谷歌上广泛搜索了错误消息和一般问题,但没有发现任何似乎已解决的相同问题。
这是相关代码。 filepath
为待加密文件的相对路径。 pgp_key_name
是包含 public 键的 .asc 文件的名称。 pgp_key_dir
是它所在的目录。
def pgp_encrypt_file(filepath, pgp_key_name, pgp_key_dir):
gpg = gnupg.GPG()
output_full_filepath = filepath + '.pgp'
try:
with open(pgp_key_dir + pgp_key_name) as file:
key_data = file.read()
import_result = gpg.import_keys(key_data)
logger.info(msg='Public key imported: {}'.format(pgp_key_name))
public_keys = gpg.list_keys()
fingerprint = public_keys[0]['fingerprint']
logger.info(msg='Attempting to encrypt file: ' +
output_full_filepath)
with open(filepath, 'r') as f:
newfile = f.read()
status = gpg.encrypt(newfile, fingerprint,
output=output_full_filepath)
logger.info(msg='status.ok : ' + str(status.ok))
logger.info(msg='status.status : ' + str(status.status))
except FileNotFoundError as e:
logger.error(msg='File not found: ' + str(e))
except TypeError as e:
logger.error(msg='GNUPG TypeError: ' + str(e))
return output_full_filepath
以及日志的相关部分:
03-01 15:18:58 gnupg INFO Setting homedir to
'/home/[user]/.config/python-gnupg'
03-01 15:18:58 gnupg ERROR Could neither invoke nor terminate a
gpg process... Are you sure you specified the corrent (and full) path to the
gpg binary?
(该错误后来没有出现,我无法在 Google 或 Stack Overflow 上找到任何相关信息。)
03-04 09:04:39 gnupg WARNING Ignoring '/usr/bin/gpg' (path is a symlink)
03-04 09:04:39 gnupg ERROR Could not find binary for 'gpg'.
03-04 09:04:39 gnupg INFO Setting homedir to
'/home/[user]/.config/python-gnupg'
03-04 09:04:39 gnupg INFO
Initialised settings:
binary: /usr/bin/gpg2
binary version: `2.0.14\ncfg:pubkey:1;16;17\ncfg:cipher:2;3;4;7;8;9;10;11;12;13\ncfg:ciphername:3DES;CAST5;BLOWFISH;AES;AES192;AES256;TWOFISH;CAMELLIA128;CAMELLIA192;CAMELLIA256\ncfg:digest:1;2;3;8;9;10;11\ncfg:digestname:MD5;SHA1;RIPEMD160;SHA256;SHA384;SHA512;SHA224\ncfg:compress:0;1;2;3\n'
homedir: /home/[user]/.config/python-gnupg
ignore_homedir_permissions: False
keyring: /home/[user]/.config/python-gnupg/pubring.gpg
secring: /home/[user]/.config/python-gnupg/secring.gpg
default_preference_list: SHA512 SHA384 SHA256 AES256 CAMELLIA256 TWOFISH
AES192 ZLIB ZIP Uncompressed
keyserver: hkp://wwwkeys.pgp.net
options: None
verbose: False
use_agent: False
03-04 09:04:39 gnupg INFO Importing: [first few lines of public key]
03-04 09:04:39 root INFO Public key imported: [name of key]
03-04 09:04:39 root INFO Attempting to encrypt file: [file]
03-04 09:04:39 gnupg INFO Writing encrypted output to file:
[file.pgp]
03-04 09:04:39 gnupg INFO Encrypted output written successfully.
我们尝试过的一些想法和事情:
虽然 /usr/bin/gpg 中有一个 gpg 二进制文件,但我们正在为项目本身使用 conda 虚拟环境,我认为这可能会搞砸。但是,当我从命令行 运行 这段代码时,在环境停用的情况下,我得到了相同的结果。
我看到日志文件说它找不到 gpg 二进制文件,并且它忽略了指向它的符号链接,但是此后的所有状态消息似乎都表明加密很好,而且它再次工作得很好使用不同的 public/private 密钥对多次。
检查 IDE 中的 pgp
对象一旦实例化,我认为它发现 gpg 二进制文件很好,即使没有将任何参数传递给 gnupg.GPG()
.传入 gnupghome='/usr/bin/gpg'
将我带到同一个地方,传入 gnupghome='not/real/path
会引发错误。
在调用 encrypt
时设置 armor=False
没有任何改变。
我非常感谢对此事的任何和所有想法。
如果答案是它只是没有在正确的目录中寻找 gpg 二进制文件或 homedir
,由于我们的虚拟环境设置,也将不胜感激关于如何解决这个问题的建议。
已解决。
在这种情况下,这是客户的错误。我们后来尝试使用各种略有不同的选项来加密文件,包括许多从命令行和 Python 完成的选项。
他们能够解密每一个。
为了帮助其他人,以下是自开始这段旅程以来我学到的一些东西:
有两个不同的包,都命名为python-gnupg。
由于这些包共享一个名称,因此在谷歌搜索其中一个或另一个错误时非常令人困惑。做 pip install python-gnupg
似乎总是下载第二个。我的经验几乎完全是第二个,所以在阅读 post.
中的其他内容时请记住这一点
在 CentOS 6 上,/usr/bin/gpg
是指向 /usr/bin/gpg2
的符号链接。 Python-GNUPG 记录错误并注意到这一点,但随后它似乎发现 /usr/bin/gpg2
就好了。
关于错误 Could neither invoke nor terminate a gpg process...
:虽然这让我很担心,但这似乎对任何功能都没有任何影响。您的里程可能会有所不同。
Python-GNUPG 版本和 gpg 二进制版本之间可能存在兼容性问题。这会导致 Unknown status message: [SOME-GPG-MESSAGE]
错误;例如: Unknown status message: PINENTRY_LAUNCHED
我认为当 gpg 试图显示密码提示时出现(在旧版本中它不会这样做!)。如果您不想在不同的操作系统上制作具有不同用途的模块(我们是),您可以在 pip install
包后手动编辑 python-gnupg 源代码试试运气。具体来说,在_handle_status
方法中的pretty_bad_protocol._parsers.py
中,有一个已知状态消息的元组;只需在其中添加任何 "unknown" 状态消息,以后就不会出现该错误。我的意思是,在那之后你就靠自己了,但这是我们尝试过的事情,似乎没有造成任何伤害。
祝以后尝试进行 pgp 加密的人好运。
感谢您提供所有详细信息。
我已经通过
解决了这个问题
gpg = gnupg.GPG(binary='/usr/bin/gpg2', homedir='/tmp')
我正在尝试使用 python-gnupg 和客户端提供的 public 密钥在 Python 3.6 中加密文本文件,他们有私钥用它解密。我无权访问该密钥。尽管 python-gnupg 出现 成功加密文件(尽管日志中出现一些令人困惑的错误),客户端无法解密它。我们被告知他们得到的错误是 gpg: decryption failed: No secret key
当我们测试使用 Cryptophane(不同的计算机,运行 Windows 而不是 Ubuntu)和相同的 public 密钥加密文件时,他们能够解密它。这就是几个月来手动成功加密的方式。当使用 我们的 公司 public 密钥测试相同的代码时,我们能够使用我们的私钥和 Cryptophane 对其进行解密。
我在谷歌上广泛搜索了错误消息和一般问题,但没有发现任何似乎已解决的相同问题。
这是相关代码。 filepath
为待加密文件的相对路径。 pgp_key_name
是包含 public 键的 .asc 文件的名称。 pgp_key_dir
是它所在的目录。
def pgp_encrypt_file(filepath, pgp_key_name, pgp_key_dir):
gpg = gnupg.GPG()
output_full_filepath = filepath + '.pgp'
try:
with open(pgp_key_dir + pgp_key_name) as file:
key_data = file.read()
import_result = gpg.import_keys(key_data)
logger.info(msg='Public key imported: {}'.format(pgp_key_name))
public_keys = gpg.list_keys()
fingerprint = public_keys[0]['fingerprint']
logger.info(msg='Attempting to encrypt file: ' +
output_full_filepath)
with open(filepath, 'r') as f:
newfile = f.read()
status = gpg.encrypt(newfile, fingerprint,
output=output_full_filepath)
logger.info(msg='status.ok : ' + str(status.ok))
logger.info(msg='status.status : ' + str(status.status))
except FileNotFoundError as e:
logger.error(msg='File not found: ' + str(e))
except TypeError as e:
logger.error(msg='GNUPG TypeError: ' + str(e))
return output_full_filepath
以及日志的相关部分:
03-01 15:18:58 gnupg INFO Setting homedir to
'/home/[user]/.config/python-gnupg'
03-01 15:18:58 gnupg ERROR Could neither invoke nor terminate a
gpg process... Are you sure you specified the corrent (and full) path to the
gpg binary?
(该错误后来没有出现,我无法在 Google 或 Stack Overflow 上找到任何相关信息。)
03-04 09:04:39 gnupg WARNING Ignoring '/usr/bin/gpg' (path is a symlink)
03-04 09:04:39 gnupg ERROR Could not find binary for 'gpg'.
03-04 09:04:39 gnupg INFO Setting homedir to
'/home/[user]/.config/python-gnupg'
03-04 09:04:39 gnupg INFO
Initialised settings:
binary: /usr/bin/gpg2
binary version: `2.0.14\ncfg:pubkey:1;16;17\ncfg:cipher:2;3;4;7;8;9;10;11;12;13\ncfg:ciphername:3DES;CAST5;BLOWFISH;AES;AES192;AES256;TWOFISH;CAMELLIA128;CAMELLIA192;CAMELLIA256\ncfg:digest:1;2;3;8;9;10;11\ncfg:digestname:MD5;SHA1;RIPEMD160;SHA256;SHA384;SHA512;SHA224\ncfg:compress:0;1;2;3\n'
homedir: /home/[user]/.config/python-gnupg
ignore_homedir_permissions: False
keyring: /home/[user]/.config/python-gnupg/pubring.gpg
secring: /home/[user]/.config/python-gnupg/secring.gpg
default_preference_list: SHA512 SHA384 SHA256 AES256 CAMELLIA256 TWOFISH
AES192 ZLIB ZIP Uncompressed
keyserver: hkp://wwwkeys.pgp.net
options: None
verbose: False
use_agent: False
03-04 09:04:39 gnupg INFO Importing: [first few lines of public key]
03-04 09:04:39 root INFO Public key imported: [name of key]
03-04 09:04:39 root INFO Attempting to encrypt file: [file]
03-04 09:04:39 gnupg INFO Writing encrypted output to file:
[file.pgp]
03-04 09:04:39 gnupg INFO Encrypted output written successfully.
我们尝试过的一些想法和事情:
虽然 /usr/bin/gpg 中有一个 gpg 二进制文件,但我们正在为项目本身使用 conda 虚拟环境,我认为这可能会搞砸。但是,当我从命令行 运行 这段代码时,在环境停用的情况下,我得到了相同的结果。 我看到日志文件说它找不到 gpg 二进制文件,并且它忽略了指向它的符号链接,但是此后的所有状态消息似乎都表明加密很好,而且它再次工作得很好使用不同的 public/private 密钥对多次。
检查 IDE 中的
pgp
对象一旦实例化,我认为它发现 gpg 二进制文件很好,即使没有将任何参数传递给gnupg.GPG()
.传入gnupghome='/usr/bin/gpg'
将我带到同一个地方,传入gnupghome='not/real/path
会引发错误。在调用
encrypt
时设置armor=False
没有任何改变。
我非常感谢对此事的任何和所有想法。
如果答案是它只是没有在正确的目录中寻找 gpg 二进制文件或 homedir
,由于我们的虚拟环境设置,也将不胜感激关于如何解决这个问题的建议。
已解决。
在这种情况下,这是客户的错误。我们后来尝试使用各种略有不同的选项来加密文件,包括许多从命令行和 Python 完成的选项。 他们能够解密每一个。
为了帮助其他人,以下是自开始这段旅程以来我学到的一些东西:
有两个不同的包,都命名为python-gnupg。
由于这些包共享一个名称,因此在谷歌搜索其中一个或另一个错误时非常令人困惑。做 pip install python-gnupg
似乎总是下载第二个。我的经验几乎完全是第二个,所以在阅读 post.
在 CentOS 6 上,
/usr/bin/gpg
是指向/usr/bin/gpg2
的符号链接。 Python-GNUPG 记录错误并注意到这一点,但随后它似乎发现/usr/bin/gpg2
就好了。关于错误
Could neither invoke nor terminate a gpg process...
:虽然这让我很担心,但这似乎对任何功能都没有任何影响。您的里程可能会有所不同。Python-GNUPG 版本和 gpg 二进制版本之间可能存在兼容性问题。这会导致
Unknown status message: [SOME-GPG-MESSAGE]
错误;例如:Unknown status message: PINENTRY_LAUNCHED
我认为当 gpg 试图显示密码提示时出现(在旧版本中它不会这样做!)。如果您不想在不同的操作系统上制作具有不同用途的模块(我们是),您可以在pip install
包后手动编辑 python-gnupg 源代码试试运气。具体来说,在_handle_status
方法中的pretty_bad_protocol._parsers.py
中,有一个已知状态消息的元组;只需在其中添加任何 "unknown" 状态消息,以后就不会出现该错误。我的意思是,在那之后你就靠自己了,但这是我们尝试过的事情,似乎没有造成任何伤害。
祝以后尝试进行 pgp 加密的人好运。
感谢您提供所有详细信息。 我已经通过
解决了这个问题gpg = gnupg.GPG(binary='/usr/bin/gpg2', homedir='/tmp')