一、GPG 简介
GPG(GNU Privacy Guard)是一个开源的加密工具,用于:
- 数据加密与解密
- 数字签名与签名验证
- 安全通信与文件保护
GPG 基于非对称加密体系,使用 公钥/私钥对:
- 公钥(Public Key) :可以公开,用于加密或验证签名。
- 私钥(Private Key) :必须保密,用于解密或签名。
1.1 PGP、GnuPG 与 GPG 的历史关系
PGP(Pretty Good Privacy)
PGP 由 Phil Zimmermann 于 1991 年发布,是首个被广泛采用的个人端到端加密与数字签名系统
它最初面向电子邮件和文件加密,因其易用性和强安全性迅速流行。随后 PGP 经历多次商业收购,逐渐转为专有软件,使用受到许可限制
尽管如此,PGP 为现代个人加密实践奠定了重要基础,只是不再属于自由软件范畴
OpenPGP(开放标准)
为应对 PGP 商业化带来的兼容性与自由使用问题,社区推动其核心机制标准化
IETF 最终将算法、数据包格式和密钥管理流程规范为 OpenPGP 标准(RFC 4880,后修订为 RFC 9580)
需注意:OpenPGP 是协议规范,本身不提供具体实现
GnuPG / GPG(自由软件实现)
GnuPG(GNU Privacy Guard)是 GNU 项目对 OpenPGP 标准的官方自由软件实现,完全开源,遵循 GPLv3 协议
其命令行工具 gpg 是目前 Linux、macOS 及许多自动化系统中事实上的 OpenPGP 工具链核心
二、安装 GPG
2.1 macOS
macOS 默认不包含可用的 gpg 工具,推荐使用 Homebrew 安装:
brew install gnupg安装完成后可通过以下命令验证:
gpg --versionmacOS 图形化工具 GPG Suite
通过 Homebrew 安装的 gpg 仅包含命令行工具,不提供图形化界面
如果想要图形化管理可以在 GPG Suite 下载安装 GPG Suite
IMPORTANT其界面仅提供基础的管理与密钥信息查阅功能,且密钥生成仅支持 RSA 和 DSA 算法
这类算法在使用体验和能力上相对较旧,目前官方更推荐使用 Ed25519 和 Curve25519
因此如需使用完整功能,仍建议通过命令行工具操作
在安装 GPG Suite 时提供多个组件选择,建议全部不勾选,仅使用其提供的图形化管理工具
这样可以继续使用 Homebrew 安装的 gpg,从而避免以下问题:
- 使用到不同版本的 gpg(GPG Suite 版本更新较慢,自带 gpg 工具无法与上游同步)
- 同一系统中存在多个 gpg 可执行文件,导致调用不一致
- 配置文件不统一,私钥环或缓存数据混乱
- PATH 或 gpg-agent 冲突,引发签名或解密异常
如需要对 Apple Mail 提供 gpg 加密与签名支持,可按需勾选对应的邮件插件组件
2.2 Windows
Windows 平台推荐使用 Gpg4win 安装包:
-
内含:
- GnuPG(命令行)
- Kleopatra(密钥管理 GUI)
- 相关加密组件
安装完成后可通过以下命令验证:
gpg --version2.3 Linux
大多数 Linux 发行版默认已包含 gpg,但版本可能较旧
建议通过系统包管理器进行更新或安装最新可用版本
- Debian / Ubuntu 系
sudo apt updatesudo apt install gnupg# 或升级sudo apt upgrade gnupg- Red Hat / CentOS / Rocky / AlmaLinux
sudo dnf install gnupg# 或升级sudo dnf upgrade gnupgNOTELinux 上 gpg 一般已在系统路径中,无需额外配置
macOS 与 Windows 安装完成后,建议重启终端再验证
三、Windows 优化配置文件目录
在 Windows 上,Gpg4win 默认使用的 GnuPG 配置目录为 C:/Users/<USERNAME>/AppData/Roaming/gnupg
其中 <USERNAME> 为当前登录的用户名,可通过以下命令查看实际路径
PowerShell
"$env:APPDATA\gnupg"CMD
echo %APPDATA%\gnupg3.1 目录不一致导致的问题
在多数 Unix/Linux 环境中,GnuPG 默认使用的配置目录为 ~/.gnupg
部分跨平台工具(如 Git、IDE、构建工具 等)在 Windows 下仍沿用这一默认路径进行查找,即 C:/Users/<USERNAME>/.gnupg
当系统中仅存在 AppData/Roaming/gnupg 目录时,这类程序将无法正确找到 GPG 配置与密钥,从而导致:
- Git 提交签名失败
- IDE 无法识别已存在的 GPG 密钥
- 不同工具使用的 GPG 配置不一致
3.2 解决方案:统一配置目录
使用 cmd命令 创建目录符号链接的方式,将 .gnupg 指向 Gpg4win 实际使用的目录:
mklink /D "%USERPROFILE%\.gnupg" "%APPDATA%\gnupg"这样可以在不改变 Gpg4win 行为的前提下,兼容依赖 ~/.gnupg 路径的其他工具,实现统一的 GPG 配置与密钥管理。
NOTE创建符号链接通常需要 管理员权限,或启用 Windows 开发者模式
若不便使用符号链接,也可通过创建目录快捷方式的方式达到类似效果,但推荐优先使用符号链接
四、Pinentry 兼容性(无法输入密码)
gpg 在签名时需要弹出 Pinentry 窗口输入私钥密码。如果未配置 Pinentry 程序,会出现如下错误:
gpg: signing failed: No pinentry4.1 常见情况
- GUI pinentry(
pinentry)可能在终端或后台程序中无法弹出 - IDEA 等集成工具可能无法调用 GUI 窗口
TIP在 Linux / macOS 上,Pinentry 的图形界面仅适用于普通用户会话
使用 root(如通过 sudo / su)执行 gpg 时,默认无法弹出 Pinentry 窗口,这是正常且符合安全设计的行为
如需在 root 或无图形环境中使用 gpg,应采用 loopback 模式(见不使用 Pinentry)
4.2 解决方法
macOS
- 安装 pinentry-mac
brew install pinentry-mac- 根据你的芯片架构,将对应路径写入
gpg-agent.conf配置文件
# 备份原配置文件cp ~/.gnupg/gpg-agent.conf ~/.gnupg/gpg-agent.conf.bak 2>/dev/null || true# Apple Silicon (M1/M2/M3 等)echo "pinentry-program /opt/homebrew/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf# Intel Mac# echo "pinentry-program /usr/local/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf- 重启 gpg 以应用更改
gpgconf --kill gpg-agentgpgconf --launch gpg-agentWindows
-
确认
pinentry.exe的安装路径,以默认安装为例
该程序通常位于C:\Program Files\Gpg4win\bin\pinentry.exe -
使用命令行工具将对应路径写入
gpg-agent.conf配置文件
- powershell
# 备份原配置文件Copy-Item "$env:APPDATA\gnupg\gpg-agent.conf" "$env:APPDATA\gnupg\gpg-agent.conf.bak" -Force -ErrorAction SilentlyContinue# 写入新配置(覆盖原文件)Set-Content "$env:APPDATA\gnupg\gpg-agent.conf" 'pinentry-program "C:/Program Files/Gpg4win/bin/pinentry.exe"'- cmd
:: 备份原配置文件copy /y "%APPDATA%\gnupg\gpg-agent.conf" "%APPDATA%\gnupg\gpg-agent.conf.bak":: 写入新配置(覆盖原文件)echo pinentry-program "C:/Program Files/Gpg4win/bin/pinentry.exe" > "%APPDATA%\gnupg\gpg-agent.conf"- 重启 gpg 以应用更改
gpgconf --kill gpg-agentgpgconf --launch gpg-agent4.3 终端测试
能提示输入口令并完成签名即可说明配置生效
export GPG_TTY=$(tty)echo "test" | gpg --clearsign4.4 不使用 Pinentry
在某些场景下(如脚本、CI、无 GUI 环境),可以通过 loopback 模式 在终端中直接输入私钥密码,而不弹出 Pinentry 窗口
- 在
gpg-agent.conf中启用 loopback 支持:
allow-loopback-pinentry- 重启 gpg 以应用更改
gpgconf --kill gpg-agentgpgconf --launch gpg-agent- 使用
--pinentry-mode loopback参数进行签名或解密操作
NOTE
--pinentry-mode loopback表示允许 gpg 通过当前终端输入私钥口令,而不是调用 Pinentry 窗口
该模式必须配合gpg-agent.conf中的allow-loopback-pinentry配置,否则不会生效
在脚本或非交互环境中,通常还需要配合--passphrase-fd或--passphrase参数显式传入口令
echo "test" | gpg --pinentry-mode loopback --clearsign五、进阶配置
5.1 gpg.conf
# ==================================================# 基础输出与隐私保护# ==================================================
# 不在 ASCII armor 输出中包含 GnuPG 版本信息no-emit-version
# 不在注释字段中附加用户名、主机名等元数据no-comments
# 不显示“using insecure memory”警告(非高安全场景下可关闭)no-secmem-warning
# ==================================================# 默认密钥设置# ==================================================
# 指定默认用于签名的密钥# 建议使用完整 40 位指纹,避免多密钥环境下误用default-key ********************
# ==================================================# 密钥服务器配置(HKPS / TLS)# ==================================================
# 使用支持 TLS 的密钥服务器keyserver hkps://keys.openpgp.orgkeyserver hkps://keyserver.ubuntu.com
# 显式禁止自动从密钥服务器检索公钥# 防止在验证或解密过程中发生隐式网络访问keyserver-options no-auto-key-retrieve,no-include-revoked,no-include-disabled
# ==================================================# 算法偏好(现代安全基线)# ==================================================
# 对称加密算法偏好(用于数据加密)personal-cipher-preferences AES256 AES192 AES
# 哈希算法偏好(用于数字签名)personal-digest-preferences SHA512 SHA384 SHA256
# 为他人密钥进行认证签名(certify)时使用的哈希算法cert-digest-algo SHA512
# 标记弱哈希算法,防止被协商或降级使用weak-digest SHA1 MD5
# ==================================================# 行为与兼容性控制# ==================================================
# 是否默认将加密数据同时加密给自己(可选)# default-recipient-self
# 禁用压缩算法(可选,用于减少潜在信息泄露)# compress-algo 05.2 gpg-agent.conf
# ==================================================# Pinentry 程序配置# ==================================================
# 指定 pinentry 程序路径(macOS / Homebrew 示例)pinentry-program /opt/homebrew/bin/pinentry-mac
# ==================================================# 密码缓存策略(GPG)# ==================================================
# 普通 GPG 操作的密码缓存时间(秒)default-cache-ttl 600
# 普通 GPG 操作的最大缓存时间(秒)max-cache-ttl 7200
# ==================================================# SSH 代理缓存策略(若启用 gpg-agent 作为 ssh-agent)# ==================================================
# SSH 密钥密码缓存时间(秒)default-cache-ttl-ssh 600
# SSH 密钥密码最大缓存时间(秒)max-cache-ttl-ssh 7200非商业用途可以使用,但必须注明出处,
并且若有改编需采用相同许可协议发布。