PGP
————密码技术的完美组合
PGP简介
PGP是于1990年左右由菲利普.季默曼(Philip Zimmermann)个人编写的密码软件,现在依然在世界上被广泛使用。PGP这个名字是Pretty Good Privary(很好的隐私)的缩写。
PGP可以在Windows、Mac OS X、Linux等很多平台上运行,版本包括商用版和免费版。此外还有一个GNU遵照OpenGPG(RFC4880)规范编写的叫作GnuPG(GNU privacy Guard)的自由软件。
这里介绍的主要是根据PGP Command Line User's Guide 10.3 以及GnuPG2.1.4的内容编写的。在详细功能以及所支持的算法方面,PGP和GunPG有所区别,而且不同的版本之间也会有所不同,这里介绍统一PGP为准。
关于PGP
OpenPGP是对密文和数字签名格式进行定义的标准规格(RFC1991、RFC2440、RFC4880、RFC5581、RFC6637)。
1996年的RFC1991中对PGP的消息格式进行了定义。2007年的RFC4880中新增了对RSA和DSA的支持。2012年的RFC6637中新增了对椭圆曲线密码(ECC)的支持,并且还支持基于Curve P-256、P-384和P-521三种椭圆曲线的椭圆曲线DSA和椭圆曲线Diffie-Hellman密钥交换。
RFC6637中新增了用于比较密码学强度的平衡的对照表。由这张表可知,例如当我们选用256比特的椭圆曲线密码算法时,相应低应该选用256比特的散列散发以及密钥长度为128比特的对称密码算法。
关于GNU Privacy Guard
GNU Privacy Guard(GnuPG、GPG)是一款基于OpenPGP标准开发的密码学软件,支持加密、数字签名、密钥个管理、S/MIME、ssh等多种功能。GnuPG是基于GNU GPL协议发布的一款自由软件,因此任何人都可以自由的使用它。GnuPG本身是一款命令行攻击,但它也经常被集成到其他应用软件中。
GnuPG 分为stable、modern和classic三个系列。
- GnuPG stable 的版本号为2.0.x,支持OpenPGP、S/MIME和ssh
- GnuPG modern 的版本号为2.1.x,在stable的基础上增加了对椭圆曲线密码的支持。GnuPG modern是比较新的版本,今后将会逐渐取代现在的GnuPG stable版本。
- GnuPG classic 的版本号1.4.x,是比较旧的版本。
PGP的功能
- 对称密码
PGP支持用对称密码进行加密和解密。对称密码可以单独使用,也可以和公钥密码组合成混合密码系统。
可以使用的对称密码算法包括AES、IDEA、CAST、三重DES、Blowfish、Twofish、Camellia等。 - 公钥密码
PGP支持生成公钥密码的密钥对,以及用公钥密码进行加密和解密。实际上并不是使用公钥密码直接对明文进行加密,而是使用混合密码系统来进行加密操作。
可以使用的公钥密码算法包括RSA和ElGamal等。 - 数字签名
PGP支持数字签名的生成和验证,也可以将数字签名附加到文件中,或者从文件中分离出数字签名。
可以使用的数字签名算法包括RSA、DSA、ECDSA(椭圆曲线DSA)、EdDSA(爱德华兹曲线DSA)等。 - 单向散列函数
PGP可以使用单向散列函数计算和显示消息的散列值。
可以使用的单向散列函数算法包括SHA-1、SHA-224、SHA-256、SHA-384、SHA-512和RIPEMD-16等。MD5依然可以使用,但并不推荐。 - 证书
PGP可以生成OpenGPG中规格规定格式的证书,以及与X.509规范兼容的证书。此外,还可以颁发公钥的作废证明(revocation certificate),并可以使用CRL和OSCP对证书进行校验。 - 压缩
PGP支持数据的压缩和解压缩,压缩采用ZIP、ZLIB、BZIPZ等格式。 - 文本数据
PGP可以将二进制和文本数据相互转换。例如,当不得不使用某些无法处理二进制数的软件进行通信时,可以将二进制数据转换成文本数据(ASCII radix-64格式),这些软件就能够处理了。
radix-64格式是在邮件等场合中经常使用的base64编码基础上,增加了校验数据错误的校验和的版本。base64编码是一种可以将任何二级制数据都用AZ、az、0~9、+、/共64个字符再加上=(用于末尾填充)来表示格式。 - 大文件的拆分和拼合
在文件过大无法通过邮件发送的情况下,PGP可以将一个大文件拆分成多个文件,反过来,也可以将多个文件拼合成一个文件。 - 钥匙串的管理
PGP可以管理所生成的密钥对以及外部获取的公钥。用于管理密钥文件称为密钥串(key ring)。
生成密钥对
略
加密和解密
加密
PGP的加密过程,如图所示,消息经过混合密码系统进行加密,然后转换成报文数据(文本数据)。
这里的内容,和前面提到的混合密码系统的结构基本上是一样的,差异在于这里还包括了消息的压缩以及二进制——>文本转换(转换为ASCII radix-64)这两个步骤。
- 生成和加密会话密钥
- 用伪随机数生成器生成会话密钥。
- 用公钥密码加密会话密码,这里使用的密钥是接收者的公钥。
- 压缩和加密消息
- 压缩消息
- 使用对称密码对压缩的消息进行加密,这里使用的密钥是步骤1生成的会话密钥
- 将加密的会话密钥 步骤2与加密的消息 步骤4拼合起来。
- 将步骤5的结果转换为文本数据,转换后的结果就是报文数据。
用公钥密码加密会话密钥,用对称密码加密消息 就是混合密码系统的特点
解密
- 解密私钥
PGP的私钥是保存在用户的钥匙串中的。为了防止钥匙串被盗,私钥都是以加密状态保存的,并在保存时使用了基于口令的密码(PBE)。口令是由多个单词组成的短语,没有正确的口令就无法使用相应的私钥。如果攻击者想要使用你的私钥,就必须先窃取保存私钥的钥匙串,然后再破译加密私钥的密码。
解密私钥的步骤如下
- 接收者输入解密的口令
- 求口令的散列值,生成用于解密私钥的密钥。
- 将钥匙串中经过加密的私钥进行解密。
- 解密会话密钥
- 将报文数据(文本数据)转换成二进制数据
- 将二进制数据分解成两部分:加密的会话密钥、经过压缩和加密的消息。
- 用公钥密码解密会话密钥,这里使用步骤3中生成的接收者的私钥。
- 解密和解压缩消息
- 对步骤5中得到的经过压缩和加密的消息用对称密码进行解密。这里使用步骤6中生成的会话密钥。
- 对步骤7中得到的经过压缩的消息进行解压缩。
- 得到原始消息。
生成和验证数字签名
生成数字签名
在上图中,消息与相对应的签名进行拼合,并最终转换成报文数据(文本数据)。顺便提一下,对于是否要将报文数据转换成文本数据,在PGP是可以选择的。
- 解密私钥
在钥匙串中,私钥是通过口令进行加密保存的,因此不知道口令的人就无法使用相应的私钥。
- 发送者输入签名用的口令
- 求口令的散列值,生成用于解密私钥的密钥
- 求钥匙中经过加密的私钥进行解密。
- 生成数字签名
- 用单向散列函数计算消息的散列值
- 对步骤4中得到的散列值进行签名。这一步相当于使用步骤3中得到的私钥进行加密。
- 将步骤5中生成的数字签名与消息进行拼合
- 将步骤6的结果进行压缩。
- 将步骤7的结果转换为文本数据
- 步骤8的结果就是报文数据
验证数字签名
- 恢复发送者发送的散列值
- 将报文数据(文本数据)转换为二进制数据。
- 对经过压缩的数据进行解压缩
- 将解压缩后的数据进行分解成经过签名的散列值和消息两部分
- 将经过签名的散列值(经过加密的散列值)用发送者的公钥进行解密,恢复发送者发送的散列值。
- 对比散列值
- 将步骤3中分解出的消息输入单向散列函数计算散列值。
- 将步骤4中得到的散列值与步骤5中得到散列值进行对比
- 如果步骤6的结果相等则数字签名验证成功,不相等则验证失败。这就是数字签名的验证结果。
- 步骤3中分解出的消息就是发送者发送的消息。
生成数字签名并加密以及解密并验证数字签名
生成数字签名并加密
上图展示了对消息生成数字签名以及对消息进行压缩和加密这两个过程,并将两者的结果拼合在一起形成报文数据(文本数据)。对于是否要将报文数据转换成文本数据,在PGP中是可以选择的。
- 生成数字签名
- 加密
解密并验证数字签名
解密
验证数字签名
信任网
公钥的合法性
在使用PGP时,确认自己所得到的公钥是否真的属于正确的人是非常重要的,因为公钥可能会通过中间人攻击被替换。
证书就是由认证机构对公钥所施加的数字签名,通过验证这个数字签名就可以确认公钥合法性。
然而,PGP中却没有使用认证机构,而二十采用了一种叫作信任网(web of trust)的方法。在这种方法中,PGP用户会互相对对方的公钥进行数字签名。
信任网的要点是“不依赖认证机构”,而是建立每个人之间的信任关系。换言之,就是能够自己决定要信任哪些公钥。
该系列的主要内容来自《图解密码技术第三版》
我只是知识的搬运工
文章中的插图来源于原著