OpenPGP上手指南
久闻中本聪[1]用PGP对邮件签名,这让他保持匿名交流的同时避免身份被伪造,其背后是一种称之为OpenPGP的协议,这是什么?除了给邮件加密和签名,还有哪些用途?
简要介绍
简而言之Phil Zimmermann在1991年创造了PGP程序,然后1997年开发它的团队提出了OpenPGP协议,随后成为通用标准,任何符合这一标准的程序也被称作OpenPGP,相互兼容,其中常见的有PGP、GnuPG、OpenPGP.js等。
OpenPGP使用了对称和非对称加密,具体支持的对称算法(如AES)和非对称算法(如RSA、ECDSA)目前都没有破解的可能。对称加密和解密用的是同一个密钥,密钥如何安全传输和保存是个问题;非对称方式则是一对密钥,可以用公钥加密然后用私钥解密,或者私钥加密,公钥解密。公钥和私钥数学上等价,公钥可以公开,私钥自己保存。对称加密的性能(速度)要优于非对称加密,OpenPGP标准是以非对称方式加解密"对称加密的钥匙"[2]:
以邮件为例,实现两种功能:
- 邮件加密,A发送加密邮件给B,过程首先随机生成对称加密的钥匙,加密明文内容,同时用B的公钥加密这个钥匙,然后打包成密文一起发送给B,B收到邮件后用自己的私钥解密得到对称加密钥,再用这个钥匙解密得到明文,这意味着只要私钥不泄露对话就无法被窃听。
- 邮件签名,B发送签名邮件给A,首先用散列算法将会话内容映射成固定长度的散列值当作唯一指纹,再用自己的私钥加密散列值作为签名与内容一并发出,A用B的公钥解密得到的散列值与自己对正文内容的散列计算进行对比,完全一致从而确认签名有效,这表示邮件确实是B发出且内容没有被篡改,即便B自己也不行。
密钥对用邮箱号+口令短语生成,如果只是加密用途,邮箱其实不是必要的,口令则是额外用来加密私钥的密码,这样即便私钥被窃取,没有口令仍然无法使用。公钥公开到网上,其他人在客户端导入公钥同时取得了对应的邮箱,这样有一个好处就是不用担心邮箱被爬取收到垃圾邮件,不过由于OpenPGP非常小众,更常见的免骚扰公开邮箱的方法是用base64编码。
A如果想要加密收信和签名自己发出的邮件,也可以创建自己的密钥,公钥让B导入,一封邮件可以同时加密和签名,这样就建立了安全的对话。当然安全是个系统工程,诸如加解密前后的安全[3]、使用者的隐私保护、以及通信隧道的稳定,这些都不是靠OpenPGP解决的。
相关及类似的标准
DMARC
电子邮箱地址很容易伪造,DMARC[4]提供了关于邮箱地址的身份认证,通过域名DNS记录和发件服务端的设置约定只有从特定网络地址中的指定服务端已开通的邮箱地址获得授权,收件端据此验证发件人邮箱地址是否伪造以及授予不同的声誉度。DMARC一般用于过滤垃圾和钓鱼邮件,而非用于个人身份认证,除非域名邮箱完全个人使用。OpenPGP只认证它签名的信息,也就是说A可以换一个邮箱或者换一种渠道发出签名的信息,拥有公钥的人就可以验证是否原主,另一方面,任何人都可以基于同一组名称与邮箱生成密钥对,并据此声称自己拥有某种身份,这就需要某种信任的机制。
S/MIME
S/MIME也用于邮件的加密和签名,方式[5]和OpenPGP类似,区别在于用户的公钥由权威CA机构验证用户真实身份然后签署,收件人通过证书公钥验证发件人身份真实性,从授信的机构申请证书除了要验证真实身份,通常还要付费。而OpenPGP假定机构也是不可信任的,密钥所有者可以不与真实信息关联,那么如果很多个公钥指向同一个邮箱,哪一个才是想要找的人?其使用的是一种称为信任网的模式[6],用户给别人的公钥签名,相当于做了信任背书,一个公钥的发布者从零开始的,如同一个电子人从互联网出生,与现实中出生不同,没有附带任何社会关系,却自含了一张身份证,然后从任意一处,如博客、聊天软件开始逐步建立通信关系和信用,经过网络的扩散,也就有了信任的累加。
SSL/TLS
SSL/TLS和S/MIME、OpenPGP都是基于对称+非对称加密算法,SSL/TLS并不需要用户自己创建密钥和操作加解密,它是服务端与服务端之间,或者服务端和客户端之间建立隧道或路由时自动完成的,服务端和客户端的身份也是由CA(证书授权中心)认证,网址的https前缀,邮箱的995、993、465端口,就是默认表示SSL加密。因为密钥不是用户自己掌握的,无法保证服务端的安全,例如有些大型邮箱服务商也会扫描用户邮件以精准推送广告。如果不信任第三方服务,也有点对点加密通讯软件,点对点通信相对而言连接更不稳定和数据不方便同步备份。
区块链
区块链[7]看起来太复杂,浅显的理解,区块链是为交易设计的,同样是公私对,公钥是用私钥生成的,再用公钥生成钱包地址,A向B进行一笔转账交易,具体过程大致是用B的公钥给B的地址加密发送某个信息,例如转账金额,并用上了自己签名,发送后这一记录广播到所有矿工节点上,矿工验证签名和转账的有效性,然后把交易记录加入到不可篡改的公共账本也就是区块链上,而只有B可以用自己的私钥打开地址取出金额。根据区块链交易的特点,除了可以交易金额,也可以是非同质化代币(NFT):资产的数字指纹签名;根据公共账本的特点,除了记录交易,也可以记录其他信息,甚至保存文件,不可撤销、不可更改、充分冗余;又由于节点的计算能力,可以用来执行某些固定的程序。
那么区块链的信任网就得以通过在公共账本上查询该公钥的交易记录实现,传统上OpenPGP对于一个陌生的公钥,只能上公钥服务器上查询有没有可信的人对其进行过签名验证[8],这会带来很多问题,而如果对方没有上传过公钥,只能多渠道求证;OpenPGP是否也可以用来交易和数字确权?看起来符合法律[9]的要求,只不过缺乏相应的案例;此外如果A和B之间对话都进行签名,并在签名中包含回复和前一封来信的信息,这就有一点块链的意思了,OpenPGP通信签名和加密都不是必须的,或许任意组合可以拥有更多的自定义能力。
如何使用
OpenPGP可以用来做什么?
大概想到这么几条:
- 邮件加密和签名,这个是最常用的。不知是不是OpenPGP的问题:加密会把富文本转化为纯文本格式,因此最好以文件形式发送富文本,或用base64编码后再加密;
- 给文件加密和签名;
- 验证第三方软件的签名;
- Github为OpenPGP签名的 git commits附加了身份标识;
- 在自己的个人网页上发布公钥作为一种保留的身份证明方式;
- 为自己的的数字作品、资产签名确认著作权、所有权等;
- 为自己在其他平台的的ID提供身份证并关联通信方式;
- 为联系人提供身份验证。
设想两种从不信任建立信任的过程:
- A向B发送信息,用B的公钥加密,如果双方有不当行为,由于互相都没有证明身份,因此负面影响可以很大程度上消弭。而B为主动构建信任,开始发送签名的信息,直到A也开始签名,从而建立起信任的联系。
- A首先向B发送包含签名的信息,因为B的身份未得到确认,信息有泄漏的可能,而B用A的公钥向A发送信息,从可公开到不公开,这是信任的第二步,直到B也开始签名,从而建立信任的联系。
有哪些可用的软件
主流的邮箱平台,如Outlook、Gmail、163、QQ邮箱等都没有集成,自托管的群晖MailPlus有一个较旧版本的OpenPGP.js(v4.10.3,只能用RSA算法,Web端也可以导入GnuPG等其他工具生成的密钥,但手机客户端只能同步OpenPGP.js密钥,也就是说手机端无法同步RSA以外的算法生成的密钥),OpenPGP主要以第三方插件和应用对上述邮箱提供支持,各终端的软件可以在官网找到更多介绍:《Email Encryption - OpenPGP》,你也可以先到网页上尝试体验:OpenPGP-Web(中文)、PGP Tool (英文)。
我试过比较好用浏览器插件Mailvelope和Windows桌面软件 Gpg4win(有汉化),这些是前端图形工具,附带的后端密钥库由OpenPGP.js或GnuPG实现。介绍下它们的优点和碰到的问题:
- Mailvelope支持很多web端的邮箱,也可在设置里添加自己的域名授权;
- Mailvelope默认用OpenPGP.js作为密钥管理库,也可切换到GnuPG,需要另外安装(Windows上装Gpg4win即可);
- Mailvelope使用OpenPGP.js时无法同时解密和验证签名,显示:
Signature unknown Key with ID xxxx not found.
,这似乎是OpenPGP.js的问题[10],和GnuPG配合使用正常; - GnuPG需要用自己的密钥对联系人的公钥进行认证,否则对方的签名邮件也会无法验证;
以上就是OpenPGP的介绍,如有误还请指正。
我的OpenPGP公钥可以在个人简介 (blog.nigzu.com/about)中找到。
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。