You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python虚拟环境中gnupg库import_keys及加密功能异常的解决咨询

问题

我用以下Python代码实现PGP公钥加密文件:

import gnupg

def pgp_encrypt(pub_file, out_file):

    gpg = gnupg.GPG()

    with open(pub_file, 'rb') as pgp_pub_key:
        public_key_data = pgp_pub_key.read()

    # import_keys_file() is NOT used as the key
    # eventually will come from user-input
    import_result = gpg.import_keys(public_key_data)
    if import_result.count == 0:
        print("Error: No keys imported. Make sure the public key file is correct.")
        exit()

    pgp_key_id = import_result.results[0]['fingerprint']
    plaintext_data = b'This is the TEST data to encrypt'

    encrypted_data = gpg.encrypt(
        plaintext_data,
        recipients=[pgp_key_id],
        always_trust=True
    )

    if encrypted_data.ok:
        print("Data encrypted successfully.")
        print(encrypted_data.data)
        with open(out_file, 'wb') as encrypted_file:
            encrypted_file.write(encrypted_data.data)
    else:
        print("Encryption failed:")
        print(encrypted_data.status)

## Apply
pgp_encrypt('pgp_pubkey.asc', 'pgp_encrypted_file')

这段代码在全局Python环境中能正常运行并输出加密数据,但在虚拟环境执行时先报错:

AttributeError: 'ImportResult' object has no attribute 'count'

把count改成counts后,又出现新错误:

TypeError: GPGBase._encrypt() got multiple values for argument 'recipients'

虚拟环境创建步骤如下:

% cd ~/Scripts/gnupg
% python3 -m venv pgpenv
% source pgpenv/bin/activate
% pip install gnupg

也尝试过安装python-gnupg,结果一致。请问该如何解决?

解决方案

问题根源是全局环境和虚拟环境中python-gnupg(即gnupg包)的版本不一致,新版本API做了变更,导致代码不兼容。可以通过以下两种方式解决:

方式1:降级虚拟环境中的包版本

将虚拟环境里的gnupg包降级到和全局环境一致的版本(比如旧版0.4.x系列):

# 先查看全局环境的版本
python3 -c "import gnupg; print(gnupg.__version__)"
# 在虚拟环境中安装对应版本
pip install gnupg==x.x.x  # 替换x.x.x为全局环境的版本号

方式2:修改代码适配新版本API

如果要使用新版本(比如1.x.x系列),需要调整两处代码:

  1. 导入结果的判断:新版本中ImportResult对象没有count属性,改用import_result.imported来判断是否成功导入密钥:
    # 替换原有的count判断
    if import_result.imported == 0:
        print("Error: No keys imported. Make sure the public key file is correct.")
        exit()
    
  2. 加密方法的参数:新版本中encrypt方法的recipients参数不需要用列表包裹,直接传入指纹字符串即可:
    encrypted_data = gpg.encrypt(
        plaintext_data,
        recipients=pgp_key_id,  # 去掉列表,直接传字符串
        always_trust=True
    )
    

修改后的完整代码:

import gnupg

def pgp_encrypt(pub_file, out_file):

    gpg = gnupg.GPG()

    with open(pub_file, 'rb') as pgp_pub_key:
        public_key_data = pgp_pub_key.read()

    import_result = gpg.import_keys(public_key_data)
    if import_result.imported == 0:
        print("Error: No keys imported. Make sure the public key file is correct.")
        exit()

    pgp_key_id = import_result.results[0]['fingerprint']
    plaintext_data = b'This is the TEST data to encrypt'

    encrypted_data = gpg.encrypt(
        plaintext_data,
        recipients=pgp_key_id,
        always_trust=True
    )

    if encrypted_data.ok:
        print("Data encrypted successfully.")
        print(encrypted_data.data)
        with open(out_file, 'wb') as encrypted_file:
            encrypted_file.write(encrypted_data.data)
    else:
        print("Encryption failed:")
        print(encrypted_data.status)

pgp_encrypt('pgp_pubkey.asc', 'pgp_encrypted_file')

内容的提问来源于stack exchange,提问作者MacUsers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:13:16