GPG不接受以特殊字符开头的Passphrase,如何让其正确识别?
解决GPG密码短语含特殊字符开头的加密问题
问题根源
GPG会将以-开头的命令行参数解析为命令选项,而非密码短语,因此直接通过--passphrase传递此类密码会触发参数冲突错误。同时,命令行传递密码本身存在安全风险(会被系统进程列表捕获)。
解决方案
推荐使用以下两种方式传递密码,既避免特殊字符解析问题,又提升安全性:
方法1:通过文件描述符传递密码(分离式传递,更安全)
使用--passphrase-fd指定GPG从特定文件描述符读取密码,明文仍通过标准输入传递,两者互不干扰:
import subprocess import getpass passphrase = getpass("Please put your passphrase: ") plaintext = b"your plaintext content here" # 替换为实际明文(字节类型) command = [ "gpg", "--symmetric", "--armor", "--pinentry-mode=loopback", "--passphrase-fd", "3", "--batch" ] with subprocess.Popen( command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, pass_fds=(3,), universal_newlines=False ) as proc: # 向文件描述符3写入密码,需以换行结尾 proc.stdin.write(passphrase.encode() + b"\n") proc.stdin.flush() # 写入明文内容 proc.stdin.write(plaintext) proc.stdin.close() out, err = proc.communicate() if proc.returncode != 0: raise RuntimeError(f"GPG加密失败: {err.decode()}") print(out.decode())
方法2:通过标准输入顺序传递密码与明文(代码更简洁)
使用--passphrase-file -让GPG从标准输入读取密码,配合--batch模式按顺序读取密码和明文:
import subprocess import getpass passphrase = getpass("Please put your passphrase: ") plaintext = b"your plaintext content here" command = [ "gpg", "--symmetric", "--armor", "--pinentry-mode=loopback", "--passphrase-file", "-", "--batch" ] # 拼接密码(加换行)和明文,一次性传入标准输入 input_data = passphrase.encode() + b"\n" + plaintext try: out = subprocess.check_output( command, input=input_data, universal_newlines=False ) print(out.decode()) except subprocess.CalledProcessError as e: print(f"GPG加密失败: {e.stderr.decode()}")
说明
两种方法均避免了将密码暴露在命令行参数中,既解决了特殊字符开头的解析问题,又防止了密码通过系统进程列表泄露。
内容的提问来源于stack exchange,提问作者Oguz Gokyuzu
相关产品推荐
相关产品推荐

