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 进入密钥编辑模式
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 验证状态
gpg --card-status应能看到:
- Card Serial Number
- Signature / Encryption / Authentication key 信息
五、本地私钥清理(仅保留 stub key)
5.1 删除本地私钥
gpg --delete-secret-keys <KEYID>前提条件:
- 已确认子密钥成功写入 YubiKey
- 主密钥已完成离线备份
删除后:
- 本地不再持有任何可用私钥
- 所有操作必须插入 YubiKey 才能完成
5.2 导出本地公钥
当子密钥被移动到 YubiKey 后,公钥数据将发生变化,内部会记录对应 OpenPGP Card 的序列号信息
因此,应在完成 keytocard 操作后重新导出并发布公钥,以确保其他设备或他人能够正确识别硬件密钥位置
六、跨设备使用模型
在新设备上:
- 导入公钥
- 导入 stub key(或重新从公钥生成)
- 插入 YubiKey
gpg --import public.keygpg --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/
商业用途必须事先获得作者授权;
非商业用途可以使用,但必须注明出处,
并且若有改编需采用相同许可协议发布。
非商业用途可以使用,但必须注明出处,
并且若有改编需采用相同许可协议发布。