Python中gnupg不支持ed25519,用subprocess调用gpg解密无结果
解决Python调用GPG解密ed25519加密文件的问题
问题背景
使用gnupg Python模块(0.5.2版本)解密采用ed25519算法加密的GPG文件时失败,模块调试信息显示不支持ed25519/cv25519算法:
DEBUG:gnupg:gpg: decryption failed: secret key not available DEBUG:gnupg:[GNUPG:] END_DECRYPTION DEBUG:gnupg:stdout reader: <Thread(Thread-14, initial daemon)> WARNING:gnupg:gpg returned a non-zero error code: 2 DEBUG:gnupg:decrypt result[:100]: b'' Decryption Status: decryption failed Decryption Stderr: [GNUPG:] ENC_TO 6E9FF466ADE3A57D 18 0 gpg: encrypted with 0-bit [?] key, ID ADFAA57C, created 2022-01-20 "MYID <myid@email.com>" gpg: public key decryption failed: unknown pubkey algorithm [GNUPG:] ERROR pkdecrypt_failed 4 [GNUPG:] BEGIN_DECRYPTION [GNUPG:] DECRYPTION_FAILED gpg: decryption failed: secret key not available [GNUPG:] END_DECRYPTION
但直接在Shell执行以下命令可成功解密,说明底层GPG二进制支持该算法:
echo my_secret_pass_phrase | gpg --decrypt -o ./mydecryptedfile.txt ./myencryptedfile.gpg
你的subprocess调用问题原因
你当前的subprocess写法存在错误:当设置shell=True时,若使用列表形式传递命令,管道符|会被当作echo命令的参数,而非Shell管道语法,导致GPG并未接收到密码输入,因此虽然返回码为0,但实际未完成解密。
正确的Python调用方式
方式一:使用Shell字符串命令(简单直接)
将整个命令作为字符串传递给subprocess,确保Shell能解析管道语法:
import subprocess pass_phrase = "my_secret_pass_phrase" cmd = f'echo "{pass_phrase}" | gpg --decrypt -o ./mydecryptedfile.txt ./myencryptedfile.gpg' resp = subprocess.call(cmd, shell=True) print(f"返回码: {resp}")
注意:如果密码包含引号、反斜杠等特殊字符,需要先对密码进行转义,避免Shell解析错误。
方式二:不使用Shell(更安全,避免注入风险)
通过subprocess的管道直接将密码输入到GPG进程,无需依赖Shell:
import subprocess pass_phrase = "my_secret_pass_phrase" # 启动gpg进程,标准输入从管道读取 gpg_process = subprocess.Popen( ["gpg", "--decrypt", "-o", "./mydecryptedfile.txt", "./myencryptedfile.gpg"], stdin=subprocess.PIPE, text=True ) # 将密码写入gpg的标准输入,末尾加换行符模拟Shell的echo gpg_process.communicate(input=f"{pass_phrase}\n") # 获取返回码 resp = gpg_process.returncode print(f"返回码: {resp}")
这种方式更安全,不会受到Shell注入的影响,也无需处理密码中的特殊字符转义。
内容的提问来源于stack exchange,提问作者Y Pant
相关产品推荐
相关产品推荐

