用 OpenPGP/GnuPG 对邮件签名和加密
假设你搞了个大新闻,希望通过安全途径爆料给记者;又假如你有个互联网领域的商业创意,想发送到投资人的 QQ 邮箱,却担心友商腾讯会扫描你们的往来邮件进而窃取创意;再或者你的邮件里因为有某些不可描述的文字内容被邮件服务商给退回了……在这些情境之下,你可能需要用 OpenPGP/GnuPG 给你的邮件加密了。
OpenPGP 是广泛使用的邮件加密标准,定义在 RFC 4880 之中。而 GnuPG(又称 GPG)是 OpenPGP 的一种开源实现。
原理简述
OpenPGP 从完整性和保密性两方面保证通信安全。对邮件进行数字签名可以防止内容被篡改,对邮件进行加密保证内容不被刺探。两部分功能相互独立,可以独立或共同使用。
OpenPGP 的工作原理大体是这样的:用户针对自己的邮件地址,生成一对密钥。其中公钥是完全公开的,可以上传到公钥服务器,让通信的另一方通过邮件地址搜索到;也可以通过邮件等形式直接发送给对方。而私钥是保密的,只有用户自己知道。
现在假设用户 Alice 希望发送加密邮件给 Bob,Alice 首先需要知道 Bob 的公钥,然后利用 Bob 的公钥和自己的私钥加密邮件。Bob 收到邮件之后,用自己的私钥就可以解密。如果第三方 Carol 截获了邮件,虽然她可以获得 Bob 公开的公钥,但仍无法破译邮件内容。
有时,Alice 不在乎邮件是否被 Carol 看到,只关心内容是否被篡改。那么她可以用自己的私钥对邮件内容进行数字签名,并附在邮件中。Bob 收到邮件后利用 Alice 的公钥就可以核对信息完整性。由于没有 Alice 的私钥,Carol 不可能在修改邮件内容后生成合法的签名。
邮件签名和加密工具
作为 OpenPGP 标准的一种实现,原始的 GnuPG 是个纯命令行软件,尽管许多中文博客对其有介绍,不过看完简介仍然有可能一头雾水。好在许多工具都将 GnuPG 集成在内,对邮件签名加密并不需要直接在命令行里使用它。
OpenPGP 网站 列出了一系列邮件加密解决方案,涵盖了各种桌面和移动操作系统,有单独的应用,有常用邮件客户端和浏览器的插件,还有直接提供加密服务的邮件平台。
GPG Tools 是 macOS 上的一整套加密工具,它基于 GnuPG,包含了 Mail.app 插件、GPG 钥匙串(GPG Keychain)等工具,可以无缝集成在 macOS 自带的邮件客户端中使用。
在 iOS 下,有 iPGMail 和 oPenGP 可选。
如果你习惯直接通过 web 访问邮箱,Mailvelope 提供了 Chrome 和 Firefox 插件。
GPG Tools
软件可以在官网下载。下载完成后,建议进行 SHA256 校验——如果下载了不正确的版本,那邮件信息安全的基础就被动摇了。事实上,官网本身都是 SSL 加密传输的。
sha256sum GPG_Suite-2017.1b2.dmg
安装完成后,首次打开 Mail.app 时,会提示你创建密钥对。(软件提示是“密匙”,不过本文还是使用通用说法“密钥”,二者同义。)
生成新密钥对电子邮件地址应该与 Mail.app 中邮件账户完全一致。设置口令(passphrase)可以增强安全性,但以后每次使用时都要输入,一旦忘记,也无法恢复,安全性与便利性需要权衡。勾选“上传公钥”后,公钥会在创建完成后被自动上传到公钥服务器,全世界的人都可以通过你的电子邮件地址搜索到你的公钥,方便固然方便,不过之后就不能修改全名了。初次使用可不勾选,毕竟之后你仍然可以随时手动上传。
点击“生成密匙”,稍等片刻,就可以在 GPG Keychain 中看到新生成的密钥对。现在,可以发出第一封加密邮件了!
在“邮件”中点击“编写新邮件”,可以看到右上角出现绿色的“OpenPGP”。
OpenPGP
同时在“主题”一栏之后,出现两个按钮:加密和数字签名。
签名而不加密默认情况下,“数字签名”按钮是常亮的。而加密需要对方的公钥,在填写收件人并且获得公钥之前,始终是灰的。为了测试,你可以填上自己的邮箱地址,以打开加密按钮。
加密并签名填写邮件标题和内容之后,给自己发送一封加密邮件。很快,你可以在收件箱中看到刚才发出的邮件。对于正确配置了 GPG Tools 的收件人来说,邮件验证和解密完全是透明的,除了抬头那一栏“安全性”之外,与普通邮件没有任何区别。
如何知道对方的公钥呢?当然你可以让对方通过签名邮件发给你(在 GPG Keychain 中右击密钥,选择“Mail public key”),更通常的做法是,通过“查找公钥”工具,搜索对方电子邮件地址或 key ID 查找。公钥服务器有许多,信息是共通的,由于不可描述的原因,默认的服务器连接会超时,在“偏好设置”里改成 hkp://keys.gnupg.net
可以解决。
公开钥匙算法的一个弱点就是公钥的传播。如果 Carol 生成了一对钥匙,并伪装成 Bob 的,Alice 在收到伪造的公钥后,发送给 Bob 的邮件一旦被 Carol 截获,后者可以用自己的私钥将其解密。所以,通过邮件传送公钥时,数字签名是必要的。收到公钥后,通过可信渠道(比如打个电话啥的)核对“指纹”(fingerprint)也能避免这类攻击。
iPGMail
这款应用在 App Store 上卖 12 元人民币,我买了。与之类似的 oPenGP 卖 30,我没舍得再买。
这类软件的功能要件无非这几样:
- 生成并管理自己的一对钥匙
- 获取对方公钥
- 用钥匙给邮件加解密、签名
iPGMail 可以从 iCloud 导入钥匙,可以生成钥匙,也支持从一系列可编辑的服务器列表中下载公钥。
由于 iPGMail 是以单独应用而不是插件形式存在的,收发邮件就相对麻烦了。你可以在 iPGMail 的“Compose”标签页中生成加密/签名邮件,然后传送到 iOS 自带的客户端,由自带客户端最终发送;收到密文时,需要发送或复制到应用中,由 iPGMail 解密。
Mailvelope
TODO
折腾这么半天,终于实现了几乎全平台的加密邮件收发,现在你可以随心所欲地给你同样配置了 OpenPGP/GnuPG 的朋友们发信了——如果你真能找到的话。不得不说,开头设想的几种场景略显中二,如果不是在安全领域,这样的朋友恐怕很难成对出现。刚才看到个段子,有垃圾邮件发送者开始发送经过加密和签名的邮件,收件人解开邮件却发现是尼日利亚王子的故事——绕过邮件过滤系统并成功引起收件人的注意,这或许是加密邮件在非极端场合下最大的作用了。