819 字
4 分钟
GPG 与 YubiKey:硬件化子密钥管理

一、为什么要使用 YubiKey#

在采用 主密钥离线 + 子密钥日常使用 的 GPG 模型后,仍然存在一个核心风险:

  • 日常设备被入侵
  • 子密钥私钥仍然可能被窃取

子密钥私钥迁移至硬件设备(如 YubiKey) ,可以进一步实现:

  • 私钥不可导出
  • 所有签名 / 解密操作在硬件内部完成
  • 即使主机被完全控制,私钥材料仍不可获取

二、YubiKey 的OpenPGP 工作模式#

YubiKey 原生支持 OpenPGP Card 工作模式,OpenPGP 模块包含 S / E / A 三类子密钥的槽位,并且与现有 OpenPGP 密钥体系完全兼容

三、stub key(关键概念)#

3.1 什么是 stub key#

当子密钥被移动到 YubiKey 后:

  • 本地 不再保存子密钥私钥
  • GPG 在本地将仅保留一个 stub key(占位引用)
  • 所有实际操作通过 USB 与硬件交互完成

stub key 的作用是:

  • 告诉 GPG:该子密钥存在
  • 指明:私钥位于某个 OpenPGP Card(YubiKey)

3.2 stub key 的安全特性#

  • 不包含任何可用于恢复私钥的材料
  • 可安全复制到其他设备
  • 丢失 stub key ≠ 丢失私钥(可通过重新导入公钥并连接 YubiKey 重新建立引用)

四、将子密钥移动到 YubiKey#

4.1 进入密钥编辑模式#

Terminal window
gpg --edit-key <KEYID>

4.2 选择并移动子密钥#

gpg> key 1 # 选择子密钥(S / E / A)
gpg> keytocard # 写入 YubiKey

根据提示选择:

  • Signature key
  • Encryption key
  • Authentication key

完成后:

  • 子密钥私钥仅存在于 YubiKey
  • 本地仅保留 stub key

4.3 验证状态#

Terminal window
gpg --card-status

应能看到:

  • Card Serial Number
  • Signature / Encryption / Authentication key 信息

五、本地私钥清理(仅保留 stub key)#

5.1 删除本地私钥#

Terminal window
gpg --delete-secret-keys <KEYID>

前提条件:

  • 已确认子密钥成功写入 YubiKey
  • 主密钥已完成离线备份

删除后:

  • 本地不再持有任何可用私钥
  • 所有操作必须插入 YubiKey 才能完成

5.2 导出本地公钥#

当子密钥被移动到 YubiKey 后,公钥数据将发生变化,内部会记录对应 OpenPGP Card 的序列号信息
因此,应在完成 keytocard 操作后重新导出并发布公钥,以确保其他设备或他人能够正确识别硬件密钥位置

六、跨设备使用模型#

在新设备上:

  1. 导入公钥
  2. 导入 stub key(或重新从公钥生成)
  3. 插入 YubiKey
Terminal window
gpg --import public.key
gpg --card-status

无需迁移私钥文件,即可完成:

  • 签名
  • 解密
  • SSH 认证(如配置 A 子密钥)

七、备份与不可恢复边界(必须明确)#

7.1 可以备份的#

  • 主密钥私钥(离线)
  • 子密钥私钥(仅限迁移到硬件之前,且迁移后 gpg 将会拒绝再次导入子密钥私钥)
  • 公钥 / stub key

7.2 无法备份的#

  • 已写入 YubiKey 的私钥
  • YubiKey 内部生成或迁移后的私钥

一旦YubiKey 损坏,且没有迁移前的私钥备份,那么对应子密钥将 永久不可恢复

八、使用原则总结#

  • 主密钥: 离线保存,仅用于签发 / 吊销
  • 子密钥: 日常使用,优先迁移至硬件
  • stub key: 跨设备使用的唯一本地材料
  • 硬件密钥: 私钥不可导出,安全边界明确
GPG 与 YubiKey:硬件化子密钥管理
https://blog.33065432.xyz/posts/security-gpg-yubikey-subkeys/
✍️作者
m4passion
📅发布于
2025-09-15
©️许可协议
CC BY-NC-SA 4.0

商业用途必须事先获得作者授权;
非商业用途可以使用,但必须注明出处,
并且若有改编需采用相同许可协议发布。