通过电子邮件发送的 GPG 或其他 OpenPGP 消息应以RFC 2015格式发送。这很容易检测,可靠且有效。
基本上,您只是检查 RFC822 标头是否具有Content-Type
如下所示:
Content-Type: multipart/encrypted; boundary=whatever; protocol="application/pgp-encrypted"
理想的方法是使用 Python 中的email
andmime
模块,或者你最喜欢的 perl 中的 CPAN 等价物,但你可以使用精心设计的正则表达式更快地做到这一点。(如果您选择采用这种方式,请为 RFC822 标头查找经过预先测试的正则表达式并在此基础上进行构建,因为在前 20 次执行此操作时您会得到部分 RFC822 错误。续行,到处都是可选的空格,组件的可变顺序,不区分大小写等)
但是,如果有人只是将原始 OpenPGP 消息作为电子邮件文本发送怎么办?至少一些 MUA 会检测到这一点并将其视为正确的 OpenPGP 消息。他们是怎么做到的?基本上,你建议的方式:通过扫描身体。
第一部分是获取身体本身。如果他们只是使用纯文本邮件程序,或者不是愚蠢的花哨的邮件程序,那么它只是非多部分 RFC 822 消息的正文,这很容易。但是,如果您想处理喜欢将所有内容 HTML 化的邮件,则需要在扫描之前找到 text/plain 部分。可靠或快速地做到这一点并不算太糟糕,但两者兼而有之?
现在,您如何判断消息正文是否为 OpenPGP?RFC 4880描述了格式。特别是,请参阅第 6.2 节关于 ASCII 装甲格式。
但简而言之:寻找一个 Armor 标题行,-----BEGIN PGP MESSAGE-----
然后是零个或多个 RFC-822 标题,然后是一个空白行,然后是一个全是 base-64 字符和空格的数据块,然后是 Armor 尾行-----END PGP MESSAGE-----
。为了安全起见,您可能希望在标题和尾部之前和之后允许任意行(它不会使扫描变得更加困难)。任何匹配的内容都非常非常可能是 OpenPGP 消息;任何不可用的东西都不太可能与 GPG 一起使用。
这仍然无法处理人们可能使用的所有可能情况。如果有人发送拆分为两封电子邮件的 OpenPGP 多部分消息,拖放 OpenPGP 消息的方式使他们的邮件程序将其变成附件而不是正文,粘贴二进制 OpenPGP 消息而不是 ASCII 装甲消息, …</p>
但我怀疑只处理正确的 OpenPGP MIME 和明文正文中的原始 OpenPGP ASCII 装甲就足够了。