OpenPGP 密钥检查器与包解析器

粘贴一段 ASCII 甲胄封装的 OpenPGP 密钥、签名或消息 —— 或者载入二进制 .gpg 文件 —— 即可查看指纹、密钥 ID、用户 ID、子密钥、签名包以及原始的包结构树。完全在你的浏览器里完成;不会上传任何数据。
仅解析。本工具只解码并展示 OpenPGP 数据 —— 它从不做密码学签名验证、从不解密、也从不索要口令。要真正验证或解密,请用 GnuPG(gpg --verify、gpg -d)配合你自己的钥匙串。而且和任何工具一样:真正的私钥应该放在你的钥匙串里,而不是浏览器的标签页里。
接受全部甲胄类型:PUBLIC KEY BLOCK、PRIVATE KEY BLOCK、MESSAGE、SIGNATURE、ARMORED FILE。
二进制钥匙串导出 / .sig / .gpg —— 本地读取,绝不上传
本工具检查什么 —— 以及刻意不做什么
它会解码甲胄(标签、头部、base64 载荷、CRC-24 传输校验和),按新旧两种头部格式解析每一个包,读取 v4/v5/v6 密钥包(算法、MPI 尺寸、创建时间),计算 v4 指纹(SHA-1)与 v6 指纹(SHA-256),推导密钥 ID,列出用户 ID、子密钥和签名子包。它不会验证签名(那需要完整的 RFC 9580 §5.2.4 哈希-验证机制加上一个可信钥匙串)、不解密、也不会从密钥服务器抓取密钥。任何输出都请与 GnuPG 交叉核对:gpg --show-keys file.asc 打印指纹和用户 ID,gpg --list-packets file.asc 转储包结构。
本页的样本密钥 —— 四个“样本”按钮粘贴的是一把专为本页生成(从未在别处使用)的真实 RSA-2048 OpenPGP v4 密钥。私钥样本刻意以未加密形式存放(S2K usage 0),以便解析器展示秘密 MPI 的布局;真实导出的私钥则会显示它的密码算法与 S2K 派生方式。
自检
对内置样本密钥、一份分离签名和一条已签名消息重新运行解析器:甲胄标签、CRC-24 通过与刻意损坏、包 tag 序列、与独立计算值比对的 v4 指纹和密钥 ID、用户 ID、子密钥指纹、私钥检测,以及负面用例(垃圾输入与截断的包必须被拒绝)。不会向任何地方发送数据。
OpenPGP 从零讲起
一句话:OpenPGP 是一个用于端到端加密和数字签名的开放标准(RFC 4880,2024 年由 RFC 9580 更新),最著名的用途是保护电子邮件 —— 一切内容都以带标签的小型二进制包传输,外面通常再包一层对文本友好的“甲胄”。
什么是 OpenPGP?

PGP(“Pretty Good Privacy”)由 Phil Zimmermann 于 1991 年发布,是一个人人都能用来加密和签名消息的程序。为了摆脱单一厂商的问题,消息格式被标准化为 OpenPGP(1998 年 RFC 2440、2007 年 RFC 4880、2024 年 RFC 9580)。如今 GnuPG 是最常见的实现,同一套包格式也出现在签名的 git 提交、软件包签名、密钥服务器和 OPENPGPKEY DNS 记录中。

这个模型是端到端的:你和通信对方各自生成一对个人密钥;凡是为你的公钥加密的东西,只能用你的私钥解开,而私钥从不离开你的机器。它不像 TLS 那样依赖中央证书机构,对他人密钥的信任来自互相签署对方的密钥 —— 即“信任之网”。你是用这张网,还是干脆用带外方式(一通电话、一张名片)核对指纹,都由你决定;格式本身不强制任何一种。

什么是 OpenPGP 密钥?

一个 OpenPGP“密钥”其实是小小的一束包:一个主密钥包(你的身份锚点,通常允许签名)、一个或多个 User ID 包(“Alice <alice@example.com>”)、把这些 ID 绑定到主密钥的自签名,以及可选的、带各自绑定签名的子密钥 —— 通常是一把独立的加密子密钥,让贵重的主密钥可以保持离线。你粘贴进本页的整段甲胄数据块就是这一束。

指纹是主密钥包的哈希 —— v4 密钥用 SHA-1(20 字节),v6 密钥用 SHA-256(32 字节)—— 只对公开部分计算。密钥 ID 只是 v4 指纹的最后 8 字节(v5 是前 8 字节)。指纹是你用带外方式核对的东西,用来确保没有人在密钥到你手的路上调包;密钥 ID 是密钥服务器上的短句柄,面对坚决的攻击者并不具备抗碰撞性。

算法 ID名称在密钥中的典型用途
1RSA经典全能型;2048–4096 位,签名和/或加密
19ECDSANIST 曲线(P-256 等),签名
18ECDHCurve25519/P-256 密钥协商,加密子密钥
22EdDSAEd25519 签名(GnuPG 2.4+ 的现代默认)
25X25519与 Ed25519 主密钥配对的加密子密钥(v6 密钥)

私钥数据块在公开部分之后携带秘密数字:一个 S2K usage 字节说明它们的保护方式(0 = 未保护,254/255 = 由口令派生密钥配合一个密码算法),然后是秘密 MPI 和一个校验和。本页会显示这个保护模式,但从不索要口令、也从不尝试解密秘密材料。

什么是 OpenPGP 包(packet)?

甲胄之下,每个 OpenPGP 对象都是一串包。每个包以一个 tag 字节开头:旧格式把 4 位包类型和长度类型打包进去,新格式(CTB,第 6 位置 1)用 6 位类型和能以分块方式描述数据的长度字节。常见 tag:6 = 公钥,5 = 私钥,14 = 子密钥,13 = 用户 ID,2 = 签名,4 = 单遍签名,11 = 字面数据,8 = 压缩数据,18 = 加密且受 MDC 保护的数据。本页为找到的每个包打印 tag、头部格式、长度和十六进制转储,并在包头损坏时报出字节位置。

签名包把元数据放在哈希区和非哈希区两个子包区里。只有哈希区被签名本身覆盖;非哈希区(历史上放签发者密钥 ID)可以被传输途中的任何人随意改写,所以读者只能把它当作提示,绝不能当作事实。User ID 上的自签名才是真正把名字绑到密钥上的东西;单贴一个密钥包,说明不了任何归属。

ASCII 甲胄是文本外衣:-----BEGIN PGP PUBLIC KEY BLOCK-----、可选的头部(如 Version: 或 Comment:)、包流的 base64,以及最后一行存放 24 位 CRC 的 =xxxx。这个 CRC 只能发现传输损坏 —— 翻错一个 base64 字符本页就会标红 —— 但它不是签名,证明不了任何作者身份。

常见错误
  • 不核对指纹就信任一把密钥。任何人都能用任何名字生成密钥。在一个你已经信任的渠道上(当面、电话)核对指纹,才是整个身份认证环节。
  • 把甲胄 CRC 当成签名。“CRC OK”只说明 base64 完好地走完了这段路,仅此而已。验证是一种本页刻意不做的密码学操作。
  • 把密钥 ID 当身份。64 位密钥 ID 可以被算力普通的攻击者伪造(“密钥 ID 碰撞”);请始终引用完整指纹。
  • 把真实私钥贴进网页。哪怕像本页这样本地运行、不上传的页面,这种习惯也不该养成。这里的样本只是为演示而生成的用后即弃密钥。
  • 以为“PGP MESSAGE”就等于加密了。甲胄标签对内容只字未提 —— 本页的样本消息就是签了名但明文的,真正区分加密与字面数据的是包 tag 18 与 11。
  • 导入 v3 密钥。v3 密钥(1996 年前的设计,弱 16 位密钥 ID)自 2014 年起已废弃;本检查器刻意拒绝它们。
常见问题

本工具验证签名吗?不。它只解析并展示。签名验证需要完整的 RFC 9580 哈希尾部构造、签名者的公钥,以及你对那把密钥的信任判断 —— 那是 GnuPG 或 OpenPGP 库的工作。

它与 openpgp.js 有何不同?openpgp.js 是你可以嵌入应用的完整实现(加密、解密、签名、验证);本页是一个零依赖的检查器,用于在浏览器里阅读和审计 OpenPGP 结构。

能读取我的 GnuPG 导出吗?能 —— v4、v5、v6 密钥、分离签名和消息都可以。v3 密钥会被拒绝并附注说明(2014 年起废弃)。

为什么有十六进制输入模式?原始 OpenPGP 数据是二进制的;如果你手上有钥匙串或 .gpg 文件的十六进制转储,把十六进制贴进来,解析器会把它当作解码后的字节一样处理。

会上传任何东西吗?不会。解析、指纹计算和报告生成都在这个标签页里完成;页面完全在你的浏览器中运行。