PGP概述及原理

第1章   PGP概述及原理 PGP—PrettyGoodPrivacy(PGP意为“对保护隐私特别有用”,这是一个非常优秀的电子邮件加密软件,美国政府曾经把它归入军用类别,与导弹同属一类)是一个基于RSA公钥加密体系的邮件加密软件。可以用它对你的邮件保密以防止非授权者阅读,它还能对你的邮件加上数字签名从而使收信人可以确信邮件是你发来的。它让你可以安全地和你从未见过的人们通讯,事先并不需要任何保密的渠道用来传递密钥。它采用了:审慎的密钥管理,一种RSA和传统加密的杂合算法,用于数字签名的邮件文摘算法,加密前压缩等,还有一个良好的人机工程设计。它的功能强大,有很快的速度。而且它的源代码是免费的。 实际上PGP的功能还不止上面说的:PGP可以用来加密文件,还可以用PGP代替UUencode生成RADIX64格式(就是MIME的BASE64格式)的编码文件。PGP的创始人是美国的PhilZimmermann。他的创造性在于他把RSA公钥体系的方便和传统加密体系的高速度结合起来,并且在数字PGP是一种供大众使用的加密软件。加密是为了安全,私密权是一种基本人权。在现代社会里,电子邮件和网络上的文件传输已经成为生活的一部分。邮件的安全问题就日益突出了,大家都知道在Internet上传输的数据是不加密的。如果你自己不保护自己的信息,第三者就会轻易获得你的隐秘。还有一个问题就是信息认证,如何让收信人确信邮件没有被第三者篡改,就需要数字签名技术。RSA公钥体系的特点使它非常适合用来满足上述两个要求:保密性(Privacy)和认证性(Authentication)。 RSA(Rivest-Shamir-Adleman)算法是一种基于大数不可能质因数分解假设的公钥体系。简单地说就是找两个很大的质数,一个公开给世界,一个不告诉任何人。一个称为“公钥”,另一个叫“私匙”(Publickey&SecretkeyorPrivatekey)。这两个密钥是互补的,就是说用公钥加密的密文可以用私匙解密,反过来也一样。假设甲要寄信给乙,他们互相知道对方的公钥。甲就用乙的公钥加密邮件寄出,乙收到后就可以用自己的私匙解密出甲的原文。由于没别人知道乙的私匙所以即使是甲本人也无法解密那封信,这就解决了信件保密的问题。另一方面由于每个人都知道乙的公钥,他们都可以给乙发信,那么乙就无法确信是不是甲的来信。认证的问题就出现了,这时候数字签名就有用了。 在说明数字签名前先要解释一下什么是“邮件文摘”(messagedigest),单地讲就是对一封邮件用某种算法算出一个能体现这封邮件“精华”的数来,一旦邮件有任何改变这个数都会变化,那么这个数加上作者的名字(实际上在作者的密钥里)还有日期等等,就可以作为一个签名了。确切地说PGP是用一个128位的二进制数作为“邮件文摘”的,用来产生它的算法叫MD5(messagedigest5),MD5的提出者是RonRivest,PGP中使用的代码是由ColinPlumb编写的,MD5本身是公用软件。所以PGP的法律条款中没有提到它。MD5是一种单向散列算法,它不像CRC校验码,很难找到一份替代的邮件而与原件具有一样的“精华”。 回到数字签名上来,甲用自己的私匙将上述的128位的“精华”加密,附加在邮件上,再用乙的公钥将整个邮件加密。这样这份密文被乙收到以后,乙用自己的私匙将邮件解密,得到甲的原文和签名,乙的PGP也从原文计算出一个128位的“精华”来再用甲的公钥解密签名得到的数比较,如果符合就说明这份邮件确实是甲寄来的。这样两个要求都得到了满足。 PGP还可以只签名而不加密,这适用于公开发表声明时,声明人为了证实自己的身份(在网络上只能如此了),可以用自己的私匙签名。这样就可以让收件人能确认发信人的身份,也可以防止发信人抵赖自己的声明。这一点在商业领域有很大的应用前途,它可以防止发信人抵赖和信件被途中篡改。 那么为什么说PGP用的是RSA和传统加密的杂合算法呢?因为RSA算法计算量极大在速度上不适合加密大量数据,所以PGP实际上用来加密的不是RSA本身,而是采用了一种叫IDEA的传统加密算法。我先解释一下什么叫传统加密,简单地说就是用一个密钥加密明文,然后用同样的密钥解密。这种方法的代表是DES(USFederalDataEncryptionStandard),也就是乘法加密,它的主要缺点就是密钥的传递渠道解决不了安全性问题,不适合网络环境邮件加密需要。IDEA是一个有专利的算法,专利持有者是ETH和一个瑞士公司:Ascom-TechAG。非商业用途的IDEA实现不用向他们交纳费用。IDEA的加(解)密速度比RSA快得多,所以实际上PGP是用一个随机生成密钥(每次加密不同)用IDEA算法对明文加密,然后用RSA算法对该密钥加密。这样收件人同样是用RSA解密出这个随机密钥,再用IDEA解密邮件本身。这样的链式加密就做到了既有RSA体系的保密性,又有IDEA算法的快捷性。PGP的创意有一半就在这一点上了,为什么RSA体系70年代就提出来,一直没有推广应用呢?速度太慢!那么PGP创意的另一半在哪儿呢?下面我再谈PGP的密钥管理。 一个成熟的加密体系必然要有一个成熟的密钥管理机制配套。公钥体制的提出就是为了解决传统加密体系的密钥分配难保密的缺点。比如网络hacker们常用的手段之一就是“监听”,如果密钥是通过网络传送就太危险了。举个例子:NovellNetware的老版本中,用户的密码是以明文在线路中传输的,这样监听者轻易就获得了他人的密码。当然Netware4.1中数据包头的用户密码现在是加密的了。对PGP来说公钥本来就要公开,就没有防监听的问题。但公钥的发布中仍然存在安全性问题,例如公钥的被篡改(PublicKeyTampering),这可能是公钥密码体系中最大的漏洞,因为大多数新手不能很快发现这一点。你必须确信你拿到的公钥属于它看上去属于的那个人。为了把这个问题说清楚,我举个例子,然后再说如何正确地用PGP堵住这个漏洞。 以你和Alice的通信为例,假设你想给Alice发封信,那你必须有Alice的公钥,你从BBS上下载了Alice的公钥,并用它加密了信件用BBS的Email功能发给了Alice。不幸地,你和Alice都不知道,另一个用户叫Charlie的用户潜入BBS,把他自己用Alice的名字生成的密钥对中的公钥替换了Alice的公钥。那你用来发信的公钥就不是Alice的而是Charlie的,一切看来都很正常,因为你拿到的公钥的用户名是“Alice”。于是Charlie就可以用他手中的私匙来解密你给Alice的信,甚至他还可以用Alice真正的公钥来转发你给Alice的信,这样谁都不会起疑心,他如果想改动你给Alice的信也没问题。更有甚者,他还可以伪造Alice的签名给你或其他人发信,因为你们手中的公钥是伪造的,你们会以为真是Alice的来信。 防止这种情况出现的最好办法是避免让任何其他人有机会篡改公钥,比如直接从Alice手中得到她的公钥,然而当她在千里之外或无法见到时,这是很困难的。PGP发展了一种公钥介绍机制来解决这个问题。举例来说:如果你和Alice有一个共同的朋友David,而David知道他手中的Alice的公钥是正确的(关于如何认证公钥,PGP还有一种方法,后面会谈到,这里假设David已经和Alice认证过她的公钥)。这样David可以用他自己的私匙在Alice的公钥上签名(就是用上面讲的签名方法),表示他担保这个公钥属于Alice。当然你需要用David的公钥来校验他给你的Alice的公钥,同样David也可以向Alice认证你的公钥,这样David就成为你和Alice之间的“介绍人”。这样Alice或David就可以放心地把David签过字的Alice的公钥上载到BBS上让你去拿,没人可能去篡改它而不被你发现,即使是BBS的管理员。这就是从公共渠道传递公钥的安全手段。 有人会问:那你怎么安全地得到David的公钥呢,这不是个先有鸡还是先有蛋的问题吗?确实有可能你拿到的David的公钥也是假的,但这就要求这个捣蛋者参与这整个过程,他必须对你们三人都很熟悉,还要策划很久,这一般不可能。当然,PGP对这种可能也有预防的建议,那就是由一个大家普遍信任的人或机构担当这个角色。他被称为“密钥侍者”或“认证权威”,每个由他签字的公钥都被认为是真的,这样大家只要有一份他的公钥就行了,认证这个人的公钥是方便的,因为他广泛提供这个服务,假冒他的公钥是很极困难的,因为他的公钥流传广泛。这样的“权威”适合由非个人控制组织或政府机构充当,现在已经有等级认证制度的机构存在。 对于那些非常分散的人们,PGP更赞成使用私人方式的密钥转介方式,因为这样有机的非官方更能反映出人们自然的社会交往,而且人们也能自由地选择信任的人来介绍。总之和不认识的人们见面一样。每个公钥有至少一个“用户名”(UserID),请尽量用自己的全名,最好再加上本人的Email地址,以免混淆。 注意!你所必须遵循的一条规则是:在你使用任何一个公钥之前,一定要首先认证它!!!无论你受到什么诱惑,当然会有这种诱惑,你都不要,绝对不要,直接信任一个从公共渠道(由其是那些看起来保密的)得来的公钥,记得要用熟人介绍的公钥,或者自己与对方亲自认证。同样你也不要随便为别人签字认证他们的公钥,就和你在现实生活中一样,家里的房门钥匙你是只会交给信任的人的。 下面,我讲讲如何通过电话认证密钥。每个密钥有它们自己的标识(keyID),keyID是一个八位十六进制数,两个密钥具有相同keyID的可能性是几十亿分之一,而且PGP还提供了一种更可靠的标识密钥的方法:“密钥指纹”(key'sfingerprint)。每个密钥对应一串数字(十六个八位十六进制数),这个数字重复的可能就更微乎其微了。而且任何人无法指定生成一个具有某个指纹的密钥,密钥是随机生成的,从指纹也无法反推出密钥来。这样你拿到某人的公钥后就可以和他在电话上核对这个指纹,从而认证他的公钥。如果你无法和Alice通电话的话,你可以和David通电话认证David的公钥,从而通过David认证了Alice的公钥,这就是直接认证和间接介绍的结合。 这样又引出一种方法,就是把具不同人签名的自己的公钥收集在一起,发送到公共场合,这样可以希望大部分人至少认识其中一个人,从而间接认证了你的公钥。同样你签了朋友的公钥后应该寄回给他,这样就可以让他可以通过你被你其他朋友认证。有点意思吧,和现实社会中人们的交往一样。PGP会自动为你找出你拿到的公钥中有哪些是你的朋友介绍来的,那些是你朋友的朋友介绍来的,哪些则是朋友的朋友的朋友介绍的……它会帮你把它们分为不同的信任级别,让你参考决定对它们的信任程度。你可以指定某人有几层转介公钥的能力,这种能力是随着认证的传递而递减的。 转介认证机制具有传递性,这是个有趣的问题。PGP的作者PhilZimmermann。有句话:“信赖不具有传递性;我有个我相信决不撒谎的朋友。可是他是个认定总统不撒谎的傻瓜,可很显然我并不认为总统决不撒谎。” 关于公钥的安全性问题是PGP安全的核心,我在这里就不细说了。和传统单密钥体系一样,私匙的保密也是决定性的。相对公钥而言,私匙不存在被篡改的问题,但存在泄露的问题。RSA的私匙是很长的一个数字,用户不可能将它记住,PGP的办法是让用户为随机生成的RSA私匙指定一个口令(passphase)。只有通过给出口令才能将私匙释放出来使用,用口令加密私匙的方法保密程度和PGP本身是一样的。所以私匙的安全性问题实际上首先是对用户口令的保密。当然私匙文件本身失密也很危险,因为破译者所需要的只是用穷举法试探出你的口令了,虽说很困难但毕竟是损失了一层安全性。在这里只用简单地记住一点,要像任何隐私一样保藏你的私匙,不要让任何人有机会接触到它。 PGP在安全性问题上的精心考虑体现在PGP的各个环节。比如每次加密的实际密钥是个随机数,大家都知道计算机是无法产生真正的随机数的。PGP程序对随机数的产生是很审慎的,关键的随机数像RSA密钥的产生是从用户瞧键盘的时间间隔上取得随机数种子的。对于磁盘上的randseed.bin文件是采用和邮件同样强度的加密的。这有效地防止了他人从你的randseed.bin文件中分析出你的加密实际密钥的规律来。 在这里我提一下PGP的加密前预压缩处理,PGP内核使用PKZIP算法来压缩加密前的明文。一方面对电子邮件而言,压缩后加密再经过7bits编码密文有可能比明文更短,这就节省了网络传输的时间。另一方面,明文经过压缩,实际上相当于经过一次变换,信息更加杂乱无章,对明文攻击的抵御能力。PKZIP算法是一个公认的压缩率和压更强。PGP中使用的PKZIP算法是经过原作者同意的PKZIP2.0版本兼容的算法。 好了,关于PGP安全性的问题我会在《PGP的安全性》一文中专门介绍。我上面讲了这么多只是为了让大家知道PGP会是非常安全的,只要你自己遵循正确的使用方法。 第2章   PGP的密钥管理 一个成熟的加密体系必然要有一个成熟的密钥管理机制配套。公钥体制的提出就是为了解决传统加密体系的密钥分配过程保密的缺点。比如网络黑客们常用的手段之一就是"监听",如果密钥是通过网络传送就太危险了。对PGP来说公钥本来就要公开,就没有防监听的问题。但公钥的发布中仍然存在安全性问题,例如公钥被篡改(publickeytampering),这可能是公钥密码体系中最大漏洞。用户必须确信用户的公钥属于需要收信的那个人。 为了把这个问题说清楚,先举个例子进行说明,然后再说如何正确使用PGP堵住这个漏洞。 以用户A和用户B通信为例,现假设用户A想给用户B发信,首先用户A就必需获取用户B的公钥,用户A从BBS上下载或其它途径得到了B的公钥,并用它加密了信件发给了B。不幸的是,用户A和B都不知道,另一个用户C潜入BBS或网络中,侦听或截取到用户B的公钥,然后在自己的PGP系统中用用户B的名字生成密钥对中的公钥替换了用户B的公钥,并放在BBS上或直接以用户B的身份把更换后的用户B的“公钥”发给用户A。那用户A用来发信的公钥是已经是更改过的,实际上是用户C伪装用户B生成的另一个公钥。这样谁都不会起疑心,但这样一来用户B收到用户A的来信后就不能用自己的私钥解密了,更可恶的是,用户C还可伪造用户B的签名给用户A或其他人发信,因为用户A手中的公钥是伪造,用户A会以为真是用户B的来信。 防止这种情况出现的最好办法是避免让任何其他人有机会篡改公钥,但能做到这一点的是非常困难的,一种方法是直接从用户B手中得到他的公钥,然而当他在远在他乡或在时间上根本不可达到时,这是不可办到的。 但PGP发展了一种公钥介绍机制来解决这个问题,其思路是这样的:如果用户A和用户B有一个共同的朋友D,而D知道他手中的B的公钥是正确的。这样D就成为用户A和B之间的公证人,用户B为了防止别人篡改自己的公钥,就把经过D签名的自己的公钥上载到BBS上让用户去拿,用户A想要取得用户B的公钥就必需先获取D的公钥来解密BBS或网上经过D签名的B的公钥,这样就等于加了双重保险,一般没有可能去篡改它而不被用户发现,即使是BBS的管理员。这就是从公共渠道传递公钥的安全手段。 说到这里也许有人会问想到,只通过一个签名公证力度是不是小了点,聪明的PGP当然会想到这一点,就是把不同签名自己的公钥收集在一起,发送到公共场合,这样可以希望大部分人至少认识其中一个,从而间接认证了用户的公钥。同样用户签了朋友的公钥后应该寄回给他,这样就可以让他通过该用户被该用户的其他朋友所认证。有点意思吧,和现实社会中人们的交往一样。PGP会自动根据用户拿到的公钥中有哪些是朋友介绍来的,把它们分为不同的信任级别,供用户参考决定对它们的信任程度。也可指定某人有几层转介公钥的能力,这种能力是随着认证的传递而递减的。 也许还有人会问:如何安全地得到D或其他签名朋友的公钥呢。确实有可能用户A拿到的D或其他签名的朋友的公钥也假的,但这就求这个用户C必须对你们三人甚至很多人都很熟悉,这样的可能性不大,而且必需经过长时间的策划。当然,PGP对这种可能也预防的建议,那就是由一个大家普遍信任的机构担当这个角色,他被称为认证权威机构,每个由他签过字的公钥都被认为真的,这样大家只要有他的公钥就行了,认证这个人的公钥是方便的,因他广泛提供这个服务,假冒他的公钥是极困难的,因为他的公钥流传广泛。这样的"权威机构"适合由非个人控制组织或政府机构充当,现在已经有等级认证制度的机构存在,如广东省电子商务电子认证中心(www.cnca.net)就是一个权威的认证机构。 对于那些非常分散的用户,PGP更赞成使用私人方式的密钥转介方式,因这样有的非官方途径更能反映出人们自然的社会交往,而且人们也能自由地选择信任的朋友来公证,总之和不认识的人们之间的交往一样,每个公钥至少有一个"用户名"(UserID),请尽量用自己的全名,最好再加上本人的E-mail地址,以免混淆,这就是PGP推荐使用的电话密钥认证。 PGP的每个密钥有它们自己的标识(keyID),keyID是一个8位十六进制数,两个密钥具有同keyID的可能性只有十亿分之一,而且PGP还提供了一种更可靠的标识密钥的方法:“密钥指纹”(keysfingrprint),每个密钥对应一串数字(16个2位十六进制数),这个指纹重复的可能就更微乎其微了。而且任何人无法指定生成一个具有某个指纹的密钥,密钥是随机生成的,从指纹也无法反推出密钥来。用户拿到某人密钥后就可以他在电话上核对这个指纹,从而认证他的公钥。
posted @ 2011-07-06 23:53  gxldan  阅读(2527)  评论(0编辑  收藏  举报