Skip to content

OpenPGP 智能卡

如果你需要给邮件加密、给代码提交签名,或者用密钥登录服务器,OpenPGP 是一套久经考验的解决方案。而把 OpenPGP 密钥存储在硬件安全密钥中,能让安全性更上一层楼。

什么是 PGP / GPG

一段简短的历史

1991 年,美国程序员 Phil Zimmermann 发布了 PGP(Pretty Good Privacy,"还不错的隐私")——一款让普通人也能使用强加密的软件。在那个时代,强加密技术被美国政府视为"军火",Zimmermann 因此遭到了长达三年的刑事调查。

PGP 后来成为商业软件,但它的协议被标准化为 OpenPGP——一个开放标准(RFC 4880)。任何人都可以基于这个标准开发兼容软件。

GnuPG(GNU Privacy Guard,简称 GPG)是 OpenPGP 标准最著名的开源实现,也是目前最广泛使用的版本。当人们提到"PGP 密钥"或"GPG 密钥"时,通常指的是同一个东西。

GPG 能做什么

GPG 在日常工作中有三个核心用途:

  • 加密邮件和文件:只有指定的收件人才能解开内容,任何中间人都无法窥探
  • 数字签名:证明一封邮件、一个文件、一段代码确实是你本人发出的,且没有被篡改
  • Git 提交签名:在 GitHub、GitLab 上给你的代码提交加上"已验证"标记,证明代码确实出自你手

三种密钥用途

一套完整的 OpenPGP 密钥包含三种子密钥,各有不同的职责:

签名密钥(Signing Key)

用来证明"这是我写的"

当你用签名密钥签署一封邮件或一个 Git 提交时,任何人都可以用你的公钥验证这个签名。如果内容被篡改了哪怕一个字节,签名验证就会失败。

实际场景:你在 GitHub 上提交代码,签名后会显示一个绿色的"Verified"标记,表示这个提交确实来自你的密钥。

加密密钥(Encryption Key)

用来确保"只有我能解开"

别人用你的公钥加密一段信息发给你。只有你的私钥才能解密——即使是加密者自己也无法解开。

实际场景:同事给你发一封加密邮件,讨论敏感的商业信息。邮件在传输和存储过程中始终是加密的,只有你的私钥能解开它。

认证密钥(Authentication Key)

用来证明"我是我",最典型的用途是 SSH 登录。

传统的 SSH 登录使用存储在电脑上的密钥文件。认证密钥让你可以把 SSH 密钥存储在硬件设备中,登录服务器时由设备完成认证。

实际场景:你 SSH 登录公司服务器时,不需要电脑上有任何密钥文件——插入 YuerKey,GPG 代理会自动使用设备中的密钥完成认证。

为什么需要智能卡

软件密钥的风险

传统方式是将 GPG 私钥存储在电脑的硬盘上(通常在 ~/.gnupg/ 目录中)。这带来了明显的安全隐患:

  • 恶意软件窃取:如果电脑感染了木马或后门程序,攻击者可以悄悄复制你的私钥文件
  • 硬盘被盗:笔记本电脑丢失或被盗,硬盘上的私钥可能被提取
  • 远程入侵:如果有人通过漏洞远程控制了你的电脑,私钥文件就暴露了
  • 密钥泄露无感知:最可怕的是,即使私钥被复制了,你可能完全不知道——因为复制不会留下痕迹

智能卡的解决方案

OpenPGP 智能卡彻底改变了这个局面。当密钥存储在像 YuerKey 这样的硬件设备中时:

  • 私钥永远不离开设备:电脑只能"请求设备签名"或"请求设备解密",而不能"把私钥复制出来"
  • 物理操作确认:每次使用密钥时,需要在设备上确认——恶意软件无法在后台偷偷使用
  • 拔出即断:当你拔出设备,私钥就完全不可访问——不存在"被远程使用"的可能

用一个比喻来理解:传统方式就像把保险箱的钥匙放在门口的花盆底下——方便,但不安全。智能卡就像你把钥匙随身带着,而且这把钥匙还有一个特殊的机关:它只能在锁孔里转动(签名),但绝不能被复制。

keytocard 工作流

将 GPG 密钥导入硬件设备的推荐流程如下:

第 1 步:在电脑上生成完整密钥

首先在电脑上用 GnuPG 生成一套完整的密钥,包括主密钥和三个子密钥(签名、加密、认证)。

gpg --full-generate-key

第 2 步:备份主密钥

在导入设备之前,先把主密钥(master key)导出并备份到离线存储介质上,比如加密的 U 盘。主密钥可以用来签发新的子密钥,非常重要。

gpg --export-secret-keys --armor YOUR_KEY_ID > master-key-backup.asc

将备份文件存放在安全的物理位置(如保险箱),平时不要连接到任何电脑。

第 3 步:将子密钥导入设备

使用 GnuPG 的 keytocard 命令,将三个子密钥分别导入 YuerKey 的三个密钥槽:

gpg --edit-key YOUR_KEY_ID
gpg> key 1          # 选择签名子密钥
gpg> keytocard      # 导入到设备的签名槽
gpg> key 2          # 选择加密子密钥
gpg> keytocard      # 导入到设备的加密槽
gpg> key 3          # 选择认证子密钥
gpg> keytocard      # 导入到设备的认证槽
gpg> save

注意keytocard 是一个移动操作。执行后,子密钥会从电脑上删除,只保留在设备中。这正是我们想要的效果——确保私钥只存在于硬件设备中。

第 4 步:删除电脑上残留的私钥

导入完成后,删除电脑上残留的私钥材料:

gpg --delete-secret-keys YOUR_KEY_ID

然后重新导入公钥(公钥仍然需要保留在电脑上),GnuPG 会自动检测到私钥在智能卡上,并标记为"卡上密钥"。

完成后的使用体验

从此以后,每当你需要签名、加密或 SSH 登录时:

  1. GnuPG 检测到私钥在智能卡上
  2. 提示你插入 YuerKey
  3. 你在设备上确认操作
  4. 设备内部完成密码学运算,返回结果

私钥自始至终没有离开设备。

YuerKey 的 OpenPGP 支持

协议版本

YuerKey 实现了 OpenPGP Card 3.4 规范,与 GnuPG 2.2+ 完全兼容。

支持的算法

算法类型支持的算法说明
RSARSA-2048, RSA-3072, RSA-4096传统算法,兼容性最广
NIST 椭圆曲线P-256 (secp256r1), P-384 (secp384r1)NIST 标准曲线
现代椭圆曲线Ed25519 (签名), X25519 (加密)高性能,推荐使用

重要说明

  • 暂不支持卡上生成密钥:出于安全考虑,YuerKey 目前只支持通过 keytocard 从电脑导入密钥,不支持在设备上直接生成密钥。这确保你始终有主密钥的离线备份。
  • GnuPG 完整兼容:支持 GnuPG 的所有标准智能卡操作,包括 PIN 管理、密钥信息查询、重置等
  • CCID 协议通信:通过 USB CCID(Chip Card Interface Device)协议与电脑通信,操作系统原生支持,无需安装额外驱动