Skip to content

OpenPGP 使用指南

概述

YuerKey 实现了 OpenPGP Card 3.4 规范,可以作为 GnuPG 的智能卡使用。将 GPG 私钥导入设备后,签名、解密和 SSH 认证操作都在设备内部完成,私钥永远不离开硬件。这意味着即使电脑被入侵,攻击者也无法窃取你的 GPG 私钥。

前置准备

安装 GnuPG

根据你的操作系统安装 GnuPG:

  • Windows:下载并安装 Gpg4win,包含 GnuPG、Kleopatra 图形界面和 scdaemon 智能卡守护进程。
  • macOS:通过 Homebrew 安装:
    bash
    brew install gnupg
  • Linux(Debian/Ubuntu):
    bash
    sudo apt install gnupg scdaemon
  • Linux(Fedora/RHEL):
    bash
    sudo dnf install gnupg2

验证设备识别

将 YuerKey 通过 USB 线连接到电脑后,运行以下命令确认设备被正确识别:

bash
gpg --card-status

如果一切正常,应显示卡片信息,包括:

  • Application ID(应用标识)
  • 制造商信息
  • 密钥槽状态(签名、解密、认证)
  • PIN 重试计数

如果提示找不到卡片,请检查:

  1. USB 线是否正常连接。
  2. 是否安装了 scdaemon(Linux 需要单独安装)。
  3. 是否有其他智能卡程序占用了设备。

生成并导入密钥

步骤 1:生成 GPG 密钥对

在电脑上生成 GPG 密钥:

bash
gpg --full-generate-key

按照提示选择密钥类型和参数。推荐配置:

用途推荐算法说明
主密钥Ed25519 或 RSA-4096仅用于签发子密钥和管理 UID,平时不使用
签名子密钥 [S]Ed25519 或 RSA-4096用于 Git 签名、文件签名等
加密子密钥 [E]X25519 或 RSA-4096用于文件加密、邮件加密
认证子密钥 [A]Ed25519 或 RSA-4096用于 SSH 登录

如果需要单独创建子密钥:

bash
gpg --edit-key YOUR_KEY_ID
gpg> addkey

步骤 2:备份主密钥

重要! 密钥导入设备后无法再导出。务必在导入前备份完整的私钥。

bash
# 导出完整私钥(包含主密钥和所有子密钥)
gpg --export-secret-keys --armor YOUR_KEY_ID > master-key-backup.asc

# 导出公钥
gpg --export --armor YOUR_KEY_ID > public-key.asc

# 导出吊销证书
gpg --gen-revoke YOUR_KEY_ID > revoke-cert.asc

将这些备份文件保存到安全的离线位置,如加密的 U 盘或纸质打印。

步骤 3:导入子密钥到设备

使用 keytocard 命令将子密钥逐个导入到 YuerKey 的对应密钥槽中:

bash
gpg --edit-key YOUR_KEY_ID

在交互模式下,依次操作:

# 导入签名子密钥
gpg> key 1                    # 选中第 1 个子密钥(签名)
gpg> keytocard                # 导入到卡片
Please select where to store the key:
   (1) Signature key
Your selection? 1             # 选择签名槽

# 导入加密子密钥
gpg> key 1                    # 取消选中第 1 个子密钥
gpg> key 2                    # 选中第 2 个子密钥(加密)
gpg> keytocard
   (2) Encryption key
Your selection? 2             # 选择加密槽

# 导入认证子密钥
gpg> key 2                    # 取消选中第 2 个子密钥
gpg> key 3                    # 选中第 3 个子密钥(认证)
gpg> keytocard
   (3) Authentication key
Your selection? 3             # 选择认证槽

gpg> save                     # 保存并退出

提示keytocard 是移动操作,不是复制。执行后,电脑上该子密钥的私钥部分会被替换为一个指向智能卡的存根(stub)。这就是为什么必须先备份。

步骤 4:验证导入结果

bash
gpg --card-status

应在输出中看到三个密钥槽都显示了对应的密钥指纹:

Signature key  ....: XXXX XXXX XXXX XXXX ...
Encryption key ....: XXXX XXXX XXXX XXXX ...
Authentication key .: XXXX XXXX XXXX XXXX ...

支持的算法

类型支持的算法
RSARSA-2048、RSA-3072、RSA-4096
ECCP-256 (NIST)、P-384 (NIST)、Ed25519、X25519

使用场景

Git Commit 签名

配置 Git 使用 GPG 密钥签名提交:

bash
# 设置签名密钥
git config --global user.signingkey YOUR_KEY_ID

# 开启默认签名
git config --global commit.gpgsign true

# 提交代码
git commit -m "This is a signed commit"

提交时,YuerKey 屏幕会显示签名请求,按确认键完成签名。在 GitHub/GitLab 上,签名过的提交会显示「Verified」标记。

文件加密与解密

bash
# 加密文件(无需 YuerKey,使用公钥即可)
gpg --encrypt --recipient YOUR_KEY_ID document.pdf

# 解密文件(需要 YuerKey 插入)
gpg --decrypt document.pdf.gpg > document.pdf

解密时,YuerKey 屏幕会提示确认解密操作。

SSH 认证

通过 gpg-agent 将 GPG 认证子密钥用作 SSH 密钥,实现 SSH 登录时的硬件安全保护:

bash
# 1. 在 gpg-agent 配置中启用 SSH 支持
echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

# 2. 重启 gpg-agent
gpgconf --kill gpg-agent
gpg-connect-agent /bye

# 3. 设置环境变量(添加到 shell 配置文件中)
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

# 4. 获取 SSH 公钥
gpg --export-ssh-key YOUR_KEY_ID

# 5. 将输出的公钥添加到服务器的 ~/.ssh/authorized_keys

之后使用 ssh 连接服务器时,YuerKey 会提示确认认证操作。

邮件签名与加密

主流邮件客户端均支持 GPG:

  • Thunderbird:内置 OpenPGP 支持,在账户设置中配置即可。
  • Outlook(Windows):通过 Gpg4win 的 GpgOL 插件。
  • 命令行:直接使用 gpg --signgpg --encrypt 处理邮件文件。

PIN 管理

OpenPGP 智能卡使用三种 PIN 进行访问控制:

PIN 类型用途默认值最大重试次数
User PIN日常签名、解密操作的授权1234563 次
Admin PIN管理操作(修改设置、导入密钥)123456783 次
Resetting Code重置被锁定的 User PIN未设置3 次

安全提醒:首次使用务必修改默认 PIN!使用默认 PIN 等于没有保护。

修改 PIN

bash
gpg --card-edit
gpg/card> admin           # 进入管理模式
gpg/card> passwd          # 修改 PIN

按提示选择要修改的 PIN 类型:

  1. Change PIN — 修改 User PIN
  2. Unblock PIN — 使用 Resetting Code 解锁 User PIN
  3. Change Admin PIN — 修改 Admin PIN
  4. Set the Reset Code — 设置 Resetting Code

PIN 被锁定怎么办

如果 User PIN 连续输错达到最大重试次数,会被锁定:

  • 如果设置了 Resetting Code,可以用它来重置 User PIN。
  • 如果没有 Resetting Code,需要使用 Admin PIN 重置。
  • 如果 Admin PIN 也被锁定,需要进行卡片重置(会清除所有数据)。

用户交互标志(UIF)

UIF(User Interaction Flag)用于控制特定操作是否需要物理按键确认:

操作设置路径说明
签名设备设置 → OpenPGP → UIF 设置 → 签名每次签名需要按确认键
解密设备设置 → OpenPGP → UIF 设置 → 解密每次解密需要按确认键
认证设备设置 → OpenPGP → UIF 设置 → 认证每次 SSH 认证需要按确认键

启用 UIF 后,即使攻击者获得了你的 PIN,也无法在没有物理接触设备的情况下执行操作。建议至少为签名操作启用 UIF。

注意:UIF 一旦设为"永久启用"模式,将无法关闭(除非重置卡片)。请谨慎选择。

UIF 设置步骤

  1. 进入设备的 设置 菜单
  2. 选择 OpenPGP UIF 设置
  3. 为签名、解密、认证分别选择 UIF 模式:
    • 关闭:操作无需确认(默认)
    • 启用:每次操作需要物理确认
    • 永久启用:每次操作需要确认,且无法关闭

永久启用不可逆

选择"永久启用"后将无法关闭,即使重置设备也无法恢复。请谨慎选择。

状态页面

在 OpenPGP 管理界面可查看当前密钥状态,包括已导入密钥的算法类型(RSA-2048/P-256/Ed25519 等)和各槽位的 UIF 策略。

注意事项

  • 不支持卡上生成密钥:YuerKey 不支持在设备内部直接生成 GPG 密钥。必须在电脑上生成密钥后,通过 keytocard 命令导入到设备中。
  • 导入不可逆:密钥导入设备后无法以任何方式导出私钥。请务必在导入前妥善备份。
  • 算法变更会清除密钥:更改密钥槽的算法属性(如从 RSA 改为 ECC)会清除该槽中已导入的密钥。
  • 多设备使用:如果你有多个 YuerKey 或其他 OpenPGP 卡,GnuPG 可能缓存了错误的卡片序列号。遇到问题时,删除 ~/.gnupg/private-keys-v1.d/ 下的存根文件,然后重新运行 gpg --card-status