PGP工作原理简述

  PGP(Pretty Good Privacy,中文翻译“优良保密协议”)是一个基于RSA体系、将公开密钥加密与传统密钥加密相结合的用于信息加密、验证的商业应用程序,由菲尔·齐默尔曼 (Philip R. Zimmermann) 于1991年开发完成并发布。自发布以来,PGP凭借其可以运行于多种操作系统平台、其加密算法得到普遍认可、具有广泛的应用场景等特性使得PGP的应用领域迅速扩大,同时使PGP自身也得到了更好的发展。

  之后,在1997年,菲尔向 IETF 提交了OpenPGP 加密标准的提案,OpenPGP标准的详细细节可参考文档RFC 4880。OpenPGP由PGP衍生而来,是在 PGP 基础上定义的开放标准,号称是世界上使用最广泛的邮件加密标准。OpenPGP标准提供了完整的数据完整性服务,用户可以查看、检验、生成和写入加密信息、秘钥以及签名等。由于美国密码技术出口限制的制约,使得在美国境内严禁编写实现公开密钥软件的软件,即使美国公民在境外完成软件实现也不允许。鉴于此,德国人Werner Koch于1997年开始编写一款称为GPGGNU Privacy GuardGnuPG的程序,并于于1998年2月发布了第一个版本。经过一系列的开发工作,GPG 1.0.0版于1999年9月7日正式发布。GPG是一个开源的(依照GNU第三版许可),且具有和PGP相同功能的加密应用程序,其按照OpenPGP标准完成相应的设计和实现工作,是 OpenPGP 协议的一种完备的实现方案,目前由德国政府资助其研发工作。

OpenPGP is the most widely used email encryption standard in the world.

​ —— http://www.openpgp.org/

  PGP在具体过程中采用了一系列散列、数据压缩、对称密钥加密,以及公钥加密的算法。目前,PGP可以支持的操作类型包括数字签名、消息加密、压缩、电子邮件的兼容性以及分段和重装等,每个步骤均支持若干种算法,可以根据实际的应用场景和需求选择合适的算法完成工作。

基本服务

数字签名

  PGP支持消息身份认证和完整性检查。PGP用数字签名来保证接收者收到的信息一定来自于信息所声明的发送者(即身份认证),且信息在发送者和接收者之间没有被第三者修改(即完整性检查)。需要注意的是,数字签名本身不具有加密能力,在信息发送过程中会将信息和基于信息生成的签名一同发送。具体过程如下(PS:仅讨论数字签名的场景,不包含加解密操作):

  1. 发送者创建需要发送给接收者的原始信息内容;
  2. 发送者基于原始信息用SHA1算法产生一个160bit的散列值(称为消息摘要),然后用发送者自己的私钥对摘要进行加密;
  3. 发送者将第(2)步得到的加密摘要与原始信息封装成报文一同发送给接收者;
  4. 接收者收到发送者发送的报文后,通过从发送者处得到的公钥将报文中包含的摘要进行解密,获得原始未加密的摘要信息;
  5. 接收者使用相同算法针对报文中含有的原始信息生成一个新的散列值,并与第(4)步得到的解密后的摘要信息进行比对,如果两者完全匹配,则接收者收到的信息来自于发送者(因为接收者用发送者给的公钥解密了发送者发送的加密报文,即身份认证),且在发送过程中未被篡改(接收者生成的摘要和发送者发送的摘要完全匹配,即完整性检查)。

图 - 1 PGP 数字签名工作流程

  PGP采用RSA或者DSA完成数字签名的操作。在生成散列值的过程中,除了SHA1外,还支持SHA-2-256,SHA-2-354,SHA-2-512,RIPEMD-160等。

  在PGP中,数字签名可以仅作用到原始信息上,也就是可以存在若干个独立的,分别对原始信息进行了散列操作的消息摘要。以书面合同为例,如果合同涉及了多个参与方,那么每个参与方都需要在合同上签署自己的签名。如果数字签名不作用在原始信息上,那么将会产生递归签名的现象,即生成第二个签名所需要的信息中包含了第一个签名自身,当接收者收到报文后,必须依次对签名进行解密才能获得其他签名。

消息加密

  在PGP的消息加密过程中,同时使用了对称秘钥加密和公钥加密的方法对消息明文进行加密操作。这是为了保证电子邮件传输过程中的信息机密特性而做出的设计方案。对称秘钥加密具有计算量小,加密速度快,加密效率高的特点,但是对称秘钥在使用过程中需要对秘钥进行分发,秘钥的安全性无法得到保障,且秘钥的管理和维护随着秘钥的增多会越发复杂。对于公钥加密而言,其秘钥体系由公钥和私钥两个部分构成,公钥可以分发给任何需要和秘钥所有者通信的人或组织,而私钥则只能由秘钥所有者保管且绝对不能分发给任何人,所以其保密性更好。但是公钥加密由于算法自身的强度过高而导致加解密速度和对称秘钥加密相比不够理想,所以通常用来加密一些少量的、安全级别要求非常高的信息。

  鉴于二者各自的特性,PGP使用对称秘钥加密对消息明文进行加密,在加密的过程中会需要一个用来加密的秘钥(称为会话秘钥),这个会话秘钥在每次加密时重新生成,所以即使发送者向同一个接收者多次发送加密消息,每条加密消息中包含的会话秘钥都是不同的。之后,发送者利用来自接收者的公钥将会话秘钥进行加密,以此来保证在消息传输过程中会话秘钥、原始信息不会被第三者破解和篡改。最后,发送者将加密后的消息和会话秘钥封装一同发送给接收者。具体过程如下(PS:仅讨论消息加密的场景,不包含数字签名):

  1. 发送者创建需要发送给接收者的原始信息内容;
  2. 发送者生成用于对称加密的会话秘钥;
  3. 发送者采用对称秘钥算法通过第(2)步生成的会话秘钥对原始信息自身进行加密;
  4. 发送者采用来自接收者的公钥对第(2)步生成的会话秘钥进行加密;
  5. 发送者将加密后的信息和会话秘钥封装成报文一同发送给接收者;
  6. 接收者通过自己的私钥将报文中含有的加密的会话秘钥进行解密得到原始的会话秘钥;
  7. 接收者利用第(6)步得到的会话秘钥采用和发送者相同的对称秘钥算法对加密信息进行解密,得到原始信息内容。

图 - 2 PGP 加密工作流程

  有一点要注意的是,PGP可以用来自接收者的公钥对会话秘钥进行加密,也可以采用双方事先协商的加密算法或技术对会话秘钥进行加密而无需使用接收者的公钥执行会话秘钥的加密操作。

加密和签名同时使用

  PGP可以同时对原始信息做签名和加密操作,具体流程如下:

  1. 发送者创建需要发送给接收者的原始信息内容;
  2. 发送者基于原始信息用SHA1算法产生一个160bit的散列值(称为消息摘要),然后用发送者自己的私钥对摘要进行加密;
  3. 发送者将第(2)步得到的加密摘要与原始信息封装并采用ZIP算法进行压缩;
  4. 发送者生成用于对称加密的会话秘钥;
  5. 发送者采用对称秘钥算法通过第(4)步生成的会话秘钥对第(3)步生成的压缩结果进行加密;
  6. 发送者采用来自接收者的公钥对第(4)步生成的会话秘钥进行加密;
  7. 发送者将加密后的信息和会话秘钥封装成报文一同发送给接收者;
  8. 接收者通过自己的私钥将报文中含有的加密的会话秘钥进行解密得到原始的会话秘钥;
  9. 接收者利用第(8)步得到的会话秘钥采用和发送者相同的对称秘钥算法对加密信息进行解密,得到压缩后的加密摘要和原始信息;
  10. 接收者进行解压缩操作,得到加密摘要和原始信息;
  11. 接收者通过从发送者处得到的公钥将报文中包含的摘要进行解密,获得原始未加密的摘要信息;
  12. 接收者使用与发送者相同的算法针对报文中含有的原始信息生成一个新的散列值,并与第(11)步得到的解密后的摘要信息进行比对,如果两者完全匹配,则接收者收到的信息来自于发送者(因为接收者用发送者给的公钥解密了发送者发送的加密报文,即身份认证),且在发送过程中未被篡改(接收者生成的摘要和发送者发送的摘要完全匹配,即完整性检查)。

图 - 3 PGP 加密和签名工作流程

  需要注意的是,如果签名和加密都要的话,需要先做签名再做加密,这样可以保证在报文传输过程中发送者的签名信息不会被第三方篡改和替换。如果是先加密,然后对加密后的信息做签名的话,签名信息有可能在传输过程中被第三者替换。

电子邮件的兼容性

  由于PGP的执行结果是以二进制数据流的形式呈现的,所以有可能在某些电子邮件系统或者其他无法使用和处理二进制数据流的软件中无法正常的传输PGP的加密数据流,所以PGP提供了二进制数据流与文本数据之间相互转换的功能。当需要进行转换时,PGP会将二进制数据转成ASCII radix-64格式的文本数据。

  radix-64在base64的基础上额外增加了检测数据错误的校验和部分。radix-64的处理过程如下:

  1. 将二进制数据流按照每24个bit位为一组进行分组,也就是三个字节;
  2. 对于第(1)步的结果,再对每个三字节分组按照每6个bit位为一组分成四个部分;
  3. 每6个bit位的二进制数据可以对应 0 到 $ 2^6 $-1中的任一个值。这个值代表一个可打印的字符。

图 - 4 radix-64 工作示意图

图 - 5 radix-64 示例

  图中”=njUN“即为当前PGP消息的校验和内容。

图 - 6 Base64 字符集

  需要注意的是,radix-64会使得消息长度增加三分之一,但是由于在执行radix-64转换之前已经对消息进行了压缩,所以整体来看,消息的长度并未增加太多。

压缩

  PGP支持可以在有必要的情况下对数据进行压缩,压缩操作通常在加密前进行,可用的算法和格式包括了ZIP、ZLIB、BZIPZ等。之所以对数据进行压缩,一方面是因为压缩后的数据由于体积更小,减轻了传输过程中的时间和存储空间要求。另一方面,对数据进行压缩后能够提高对明文暴力攻击的抵抗能力。

  和签名一样,压缩操作也要在加密之前完成,这么做的初衷是寄希望于提高密码强度。因为压缩后的数据相较于压缩前而言,其冗余程度更低,这样当尝试利用原文中的某种规则性进行破译时,压缩由于消除了规则性而使得其强度显著提升。其次,在暴力破解的场景下,破解者需要尝试每一种秘钥来进行解密工作。如果原文为压缩后的数据,那么破解者需要考虑结果是否被压缩的情形。如果破解者在解密过程中考虑了数据被压缩的情况,那么会使得整个破解过程的时间和成本更大。

分段和重装

  为了适应最大消息量的限制,PGP可以将一个大文件拆分成若干个文件进行传输(即分段)。同时,也可以将收到的若干个文件重新重装成一个完整的文件。

涉及基础知识点

  1. 什么是数字签名?有什么作用?

    数字签名是一种使用了公钥加密算法的技术实现方案,是由发送者生成的一段可以用来鉴别数字信息内容的附加信息。数字签名由公钥加密算法中的私钥生成,通过公钥对签名进行验证和鉴别,因此,数字签名具有身份认证、完整性检查和不可抵赖等特性。通常使用数字签名防止信息在传输过程中可能遇到的伪造、篡改、抵赖等问题。

  2. 对称加密和非对称加密(公钥加密)的概念

    对称加密指的是加密和解密过程中使用的是同一个秘钥,其主要优点是加密速度快,计算量小,加密效率高的特点,但是对称秘钥在使用过程中需要对秘钥进行分发,秘钥的安全性无法得到保障,且秘钥的管理和维护随着秘钥的增多会越发复杂。

    非对称加密(公钥加密)在加密和解密过程中无需同一个秘钥就能完成相应的工作。一般而言,一个非对称加密算法的秘钥对包含了一个公钥和一个私钥,一个公钥加密只能由其对应的私钥解密,同理,一个私钥加密同样只能由其对应的公钥解密。公钥可以通过多种途径对外分发,而私钥是绝对不能对外分发的,所以其保密性更好。但是公钥加密由于算法自身的强度过高而导致加解密速度较慢,所以通常用来加密少量的信息。

  3. 散列函数

    散列函数是指将任意数据作为输入,能够输出指定长度的数值结果的函数,这个结果就称为输入数据的散列值。在密码学中,对散列函数的要求包括了取散列值的操作要非常容易,但从散列值恢复原始数据的成本大到不实际,以及输入数据的改变一定会造成散列值的变化,以及不同的信息不会产生相同的散列值等。

参考文献

  1. Phil Zimmermann
  2. Wikipedia. PGP [E]
  3. 结城浩 [日]. 图解密码技术 第三版 [M] 北京: 人民邮电出版社. 2016.
  4. 邓惠洁, 姜明富. 电子邮件系统PGP的加密原理与安全性分析 [J]. 现代计算机(专业版), 2010(14):33-35+45.
  5. 宋成勇, 胡勇, 陈淑敏, et al. PGP工作原理及其安全体制 [J]. 电子技术应用, 2004(10):49-51.
  6. 荀殿栋. PGP原理与其服务 [J]. 军事通信技术, 1998, 019(003):67-73.
  7. Ding Cunsheng. Radix-64 Conversion in PGP [E]




------------- End of this article, thanks! -------------


  版权声明:本文由N.C.Lee创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处。
  本文作者为 N.C.Lee
  本文标题为 PGP工作原理简述
  本文链接为 https://marcuseddie.github.io/2019/PGP-Introduction.html