Python-GNUPG加密文件无法用私钥解密

标签 python encryption gnupg

我正在尝试使用 python-gnupg 和客户端提供的公钥加密 Python 3.6 中的文本文件,他们有一个私钥可以用来解密它。我无权访问该 key 。尽管 python-gnupg 似乎成功加密了文件(尽管日志中出现了一些令人困惑的错误),但客户端无法解密它。我们被告知他们收到的错误是 gpg: decryption failed: No secret key

当我们测试使用 Cryptophane(不同的计算机,运行 Windows 而不是 Ubuntu)和相同的公钥加密文件时,他们能够解密它。这就是几个月来手动成功完成加密的方法。当使用我们公司的公钥测试相同的代码时,我们能够使用我们的私钥和 Cryptophane 对其进行解密。

我在谷歌上广泛搜索了错误消息和一般问题,但没有发现任何似乎是相同问题得到解决的内容。

这是相关代码。 filepath是要加密的文件的相对路径。 pgp_key_name是包含公钥的 .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.

我们尝试过的一些想法和事情:

  1. 虽然/usr/bin/gpg 中有一个 gpg 二进制文件,但我们为项目本身使用了 conda 虚拟环境,我认为这可能会搞砸。然而,当我在环境停用的情况下从命令行运行此代码时,我最终得到了相同的结果。 我看到日志文件说它找不到 gpg 二进制文件,并且它忽略了指向它的符号链接(symbolic link),但此后的所有状态消息似乎都表明加密很好,并且再次,它工作得很好使用不同的公钥/私钥对多次。

  2. 检查pgp IDE 中的对象一旦实例化,就会让我认为即使没有向 gnupg.GPG() 传递任何参数,它也能很好地找到 gpg 二进制文件。 。传入gnupghome='/usr/bin/gpg'带我到同一个地方,并传入 gnupghome='not/real/path抛出错误。

  3. 设置armor=False调用encrypt没有改变任何东西。

我真的很感激对此事的所有想法。 如果答案是它只是没有在正确的目录中查找 gpg 二进制文件或 homedir ,由于我们的虚拟环境设置,我们也将不胜感激有关如何解决该问题的建议。

最佳答案

已解决。

在本例中,这是客户端的错误。后来我们尝试使用各种略有不同的选项来加密文件,包括许多通过命令行和 Python 完成的选项。 他们能够解密每一个。

为了帮助其他人,以下是我自踏上这段旅程以来学到的一些东西:

  1. 两个不同的包,都名为 python-gnupg。

由于这些包共享一个名称,因此在谷歌搜索其中一个或另一个中的错误时非常令人困惑。执行 pip install python-gnupg 似乎总是下载第二个。我的经验几乎完全来自第二个,因此在阅读本文中的其他所有内容时请记住这一点。

  • 在 CentOS 6 上,/usr/bin/gpg 是指向 /usr/bin/gpg2 的符号链接(symbolic link)。 Python-GNUPG 记录了错误,指出了这一点,但似乎发现 /usr/bin/gpg2 就很好。

  • 关于错误既不能调用也不能终止 gpg 进程...:虽然这让我担心,但这似乎对任何功能都没有任何影响。您的里程可能会有所不同。

  • Python-GNUPG 版本和 gpg 二进制版本之间可能存在兼容性问题。这可能会导致未知状态消息:[SOME-GPG-MESSAGE]错误;例如:Unknown status message: PINENTRY_LAUNCHED 我相信当 gpg 尝试调出密码提示时会出现这种情况(在旧版本中不会这样做!)。如果您不想在不同的操作系统上创建具有不同用途的模块(我们是),您可以在 pip install 软件包后手动编辑 python-gnupg 源代码来碰碰运气。具体来说,在 _handle_status 方法的 pretty_bad_protocol._parsers.py 中,有一个已知状态消息的元组;只需在其中添加任何“未知”状态消息,将来就不会出现该错误。我的意思是,在那之后你就得靠自己了,但这是我们尝试过的事情,而且似乎没有造成任何损害。

  • 祝 future 尝试进行 pgp 加密的人好运。

    关于Python-GNUPG加密文件无法用私钥解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55034792/

    相关文章:

    python - 为什么 `numpy.ndarray.view` 会忽略之前对 `numpy.ndarray.newbyteorder` 的调用?

    python - 类的任何子类的实例的类型提示

    java - Android 将生成的 AES key 转换为字符串(base64/hex ...)

    cryptography - 由于缺少公钥,使用 rvm 安装 ruby​​s 时出现问题

    python - 在 Python 3.4 上设置 newRelic 的问题

    python - 无法使用 python 查找元音计数

    c++ - 凯撒密码输入文本文件

    java - 从 jPBC 保存和加载非对称 key

    gnupg - 无需密码即可导出 gpg key

    python-3.x - 运行时错误 : GnuPG is not installed