明文签名被认为有害
Source: Hacker News
请提供您希望翻译的正文内容,我将把它翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。谢谢!
PGP 中的明文签名 – 陷阱与验证
自 1990 年代初的首个 PGP 版本起,PGP(以及所有基于它的实现)就支持一种称为 明文签名(cleartext signature)的功能。你今天仍然会遇到此类签名。下面是一个明文签名消息的示例:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Far out in the uncharted backwaters of the unfashionable end of
the western spiral arm of the Galaxy lies a small unregarded
yellow sun.
-----BEGIN PGP SIGNATURE-----
iJEEARYKADkWIQSHd0YfKgdOvEgNNZQZzByeCFsQegUCaU5mGhsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMSwyLDIACgkQGcwcnghbEHq27gEAqE+Cw1FmIlDXyzc1+5K8
3e60/3TjpqpFmkmuot8ZROMBAIrQXMhfN3gr7jdsxLuV1L7+IzHSRyUMlelZSnAs
k+AL
=kCuN
-----END PGP SIGNATURE-----
为什么明文签名可能会产生误导
- 已签名的文本是直接可读的,但 要正确验证它需要使用 PGP 工具。仅仅查看终端输出 不足够,原因如下:
- 以短横线 (
-) 开头或以字符串From开头的行会被转义。 - 许多终端模拟器会解释转义码(例如颜色或光标移动序列),从而改变你看到的内容。
- 以短横线 (
- 确认实际签名内容的唯一可靠方法是让 PGP 实现处理整条消息,并输出 规范(canonical)的签名文本。
使用 GnuPG 验证明文签名消息
# 使用 gpg(打印状态并将已签名文本写入 signed.txt)
gpg --verify -o signed.txt message.asc
# 使用 gpgv(用于脚本;仅信任 trustedkeys.* 中的密钥)
gpgv -o signed.txt message.asc
典型输出:
gpg: Signature made Fri 26 Dec 2025 11:40:26 AM CET
gpg: using EDDSA key 8777461F2A074EBC480D359419CC1C9E085B107A
gpg: Good signature from "wk@gnupg.org" [ultimate]
...
如果诊断信息显示来自你信任的密钥的良好签名,则可以安全使用 signed.txt 的内容。
当多个密钥验证同一条消息时,它们签署的文本是完全相同的。
注意: gpgv 在自动化脚本中更为可取,因为它只接受 trustedkeys.gpg(或 trustedkeys.kbx)中列出的密钥所做的签名。gpg 的 --assert-signer 选项也可以作为替代方案。
推荐做法:使用分离签名(或 PGP/MIME)
明文签名易于阅读,但很难做到完全正确。关键在于 必须准确知道到底验证了什么。对于新消息,你应当:
-
优先使用分离签名:
# 验证分离签名 gpg --verify message.sig message.txt gpgv message.sig message.txt(此处 不要 使用
-o/--output选项;那会创建一个空文件。) -
或者,在电子邮件中使用 PGP/MIME(这是签名或加密邮件的现代标准格式)。
历史背景
在 1990 年代初,互联网尚未普及;大多数通信仍在拨号 BBS 上进行。Phil Zimmermann 设计 PGP 的初衷是让用户即使在收件人尚未安装 PGP 的情况下,也能交换 ASCII 编码的消息。
电子邮件很快取代了 BBS,但 MIME 的普及花了一段时间。1996 年,Michael Elkins 为 Mutt 邮件客户端引入了 PGP/MIME(RFC 2015),逐步取代了明文签名和明文加密的邮件。如今,PGP/MIME 已成为签名/加密消息的事实标准,尽管仍有少数客户端保留了旧的明文格式。
为什么明文签名不安全
-
装甲行篡改——
-----BEGIN PGP …头部可以通过使用更少的短横线或外观相似的 Unicode 字符来伪造,导致用户误以为签名文本比实际更早开始。 -
注释行——用户往往不知道注释行(例如
Hash:)并不是签名文本的一部分。添加额外的注释行会注入未签名的内容。 -
空行技巧——分隔装甲头部与签名文本的空行可以被终端控制或 Unicode 字符替换,从而影响实际签名范围。
-
TF‑8 字符,误导观看者。
-
过长的行 – 可能导致显示或解析异常。
这些以及过去 30 年中展示的许多其他变体,促使 PGP/MIME 被广泛采用。
Bottom line
避免对新数据使用明文签名。请改用分离签名或 PGP/MIME,并且永远不要假设屏幕上看到的文本就是被签名的内容。