文章目录
前言
阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。
本文是关于《计算机网络:自顶向下方法(第七版)》的学习分享,内容书写顺序也是按照书中的顺序。本文并不会提及书中的所有内容,主要写重点的知识,以及自己感兴趣的内容。会对原文中的内容进行一定的精简,或者加上个人的理解。
计算机网络中的安全
报文完整性和数字签名
在前面一节中我们看到了能够使用加密为两个通信实体提供机密性。 在本节中我们转向报文完整性 (message integrity) 这个同等重要的主题。报文完整性也称为报文鉴别。此外,我们将讨论两个相关的主题: 数字签名和端点鉴别。
我们再次使用 Alice 和 Bob 来定义报文完整性问题。 假定 Bob 接收到一个报文(这可能已经加密或可能是明文),并且他认为这个报文是由 Alice发送的。 为了鉴别这个报文,Bob 需要证实:
- 该报文的确源自 Alice。
- 该报文在到Bob 的途中没有被篡改。
举一个特定的例子,考虑一个使用链路状态路由选择算法(例如 OSPF) 的计算机网络,在该网络中决定每对路由器之间的路由。 在一个链路状态算法中,每台路由器需要向该网络中的所有其他路由器广播一个链路状态报文。 路由器的链路状态报文包括直接相连邻居的列表以及到这些邻居的直接费用。 一旦某台路由器从其他所有路由器收到了链路状态报文,它能够生成该网络的全图,运行它的最小费用路由选择算法并配置它的转发表。 对路由选择算法的一个相对容易的攻击是, Trudy分发具有不正确状态信息的虚假链路状态报文。 因此产生了报文完整性的需求:当路由器B收到来自路由器A的链路状态报文时,路由器B应当证实路由器A实际生成了该报文,并且进一步证实在传输过程中该报文没有被篡改。
在本节中,我们描述一种由许多安全网络协议所使用的流行报文完整性技术。 但在做此事之前,我们需要涉及密码学中的另一个重要主题,即密码散列函数。
密码散列函数
如图所示,散列函数以m为输入,并计算得到一个称为散列的固定长度的字符串H(m) 。 密码散列函数( cryptograpluc hash function ) 要求具有下列附加的性质:
- 找到任意两个不同的报文x和y使得H(x) =H(y), 在计算上是不可能的。
不严格地说,这种性质就意味着入侵者在计算上不可能用其他报文替换由散列函数保护的报文。 这就是说,如果 (m, H(m)) 是报文和由发送方生成的报文散列的话, 则入侵者不可能伪造另一个报文y的内容,使得该报文具有与原报文相同的散列值。MD5 、SHA-1等散列算法如今正在广泛使用,具体实现请自行查阅资料。

报文鉴别码
我们现在再回到报文完整性的问题。 既然我们理解了散列函数,就先来看一下将如何执行报文完整性:
- Alice 生成报文 m 并计算散列 H(m) (例如使用 SHA-1)。
- 然后 Alice 将 H(m) 附加到报文 m 上,生成一个扩展报文 (m, H(m)), 并将该扩展报文发给Bob。
- Bob 接收到一个扩展报文 (m, h) 并计算 H(m)。 如果 H(m) = h, Bob 得到结论: 一切正常。
这种方法存在明显缺陷。 Trudy 能够生成虚假报文m', 在其中声称她就是Alice, 计算H(m') 并发送给 Bob (m', H (m') ) 。 当 Bob 接收到该报文,一切将在步骤 3 中核对通过,并且Bob无法猜出这种不轨的行为。
为了执行报文完整性,除了使用密码散列函数外, Alice和 Bob将需要共享秘密s。 这个共享的秘密只不过是一个比特串,它被称为鉴别密钥 (authentication key)。 使用这个共享秘密, 报文完整性能够执行如下;
- Alice 生成报文 m, 用 s 级联 m 以生成 m + s, 并计算散列 H(m+s) (例如使用SHA- 1 ) 。 H(m +s) 被称为报文鉴别码 (Message Authentication Code, MAC) 。
- 然后Alice 将MAC 附加到报文m上,生成扩展报文 (m, H(m+s)), 并将该扩展报文发送给Bob。
- Bob 接收到一个扩展报文 (m, h) , 由于知道s, 计算出报文鉴别码H(m+ s)。 如H(m + s) = h , Bob 得到结论: 一切正常。
报文鉴别码(MAC) 的一个优良特点是它不对加密算法做硬性要求,使用MAC, 实体能够鉴别它们相互发送的报文。多年来已经提出了若干种对MAC 的不同标准。 目前最为流行的标准是HMAC, 它能够与 MD5 或SHA-1 一道使用。
这里还遗留下一个重要间题。 怎样向通信实体分发这个共享的鉴别密钥呢?例如,在链路状态路由选择算法中,在某种程度上需要向自治系统中的每台路由器分发该秘密鉴别密钥。 (注意到所有路由器都能够使用相同的鉴别密钥。)一名网络管理员能够通过物理上访问每台路由器来实际完成这项工作。 或者,如果这名网络管理员不够勤快,并且每台路由器都有它自己的公钥,那么该网络管理员能够用路由器的公钥加密鉴别密钥并分发给任何一台路由器,从而通过网络向路由器发送加密的密钥。
数字签名
回想在过去的一周中你在纸上已经签过多少次你的名字。 你可能经常会在支票、信用卡收据、法律文件和信件上签名。 你的签名证明你(而不是其他人)承认和/或同意这些文件的内容。 在数字领域,人们通常需要指出一个文件的所有者或创作者,或者表明某人认可一个文件内容。 数字签名 (digital signature) 就是一种在数字领域实现这些目标的密码技术。
正如手工签字一样,数字签名也应当以可鉴别的、不可伪造的方式进行。 这就是说,必须能够证明由某个人在一个文件上的签名确实是由该人签署的(该签名必须是可证实的) ,且只有那个人能够签署那个文件(该签名无法伪造)。
我们现在来考虑怎样设计一个数字签名方案。 当 Bob签署一个报文时,可以观察到Bob 必须将某些对他独特的东西放置在该报文上。 Bob可以考虑附加一个 MAC 用作签名,其中 MAC是由他的密钥(对他是独特的)附加到该报文上, 然后再通过散列函数得到该MAC。而Alice 为了验证该签名,她必须也具有该密钥的副本, 在这种情况下该密钥对Bob将不是唯一的。 因此,此时MAC是无法胜任这项工作的。
前面讲过使用公钥密码, Bob 具有公钥和私钥,这两种密钥对 Bob 均为独特的。 因此,公钥密钥是一种提供数字签名的优秀候选者。 我们现在来研究一下这是怎样完成的。
假设Bob 要以数字方式签署一个文档m。 我们能够想象这个文档是Bob打算签署并发送的一个文件或一个报文。 为了签署这个文档, Bob 直接使用他的私钥KB-,并选择加密算法来计算KB-(m) 。 乍一看,会感觉很奇怪, Bob 怎么会用他的私钥签署文档!(在前文,我们用私钥解密用其公钥加密的报文)但是回想加密和解密都只不过是数学运算,并且 Bob 的目的不是弄乱或掩盖文档的内容,而只是以可鉴别、不可伪造的方式签署这个文档。 Bob对文档m签名之后所得的文档就是KB-(m)。
数字签名 KB-(m) 是否满足了可鉴别、不可伪造的需求? 假设Alice有 m 和KB-(m)。她要在法庭上证明Bob确实签署过这个文档,他就是唯一能够签署该文档的人。 Alice 持有 Bob 的公钥 KB+,并把公钥用于 Bob 的数字签名 KB-(m), 从而得到了文档 m。
也就是说, Alice 计算 KB+(KB-(m) )。 瞧!在Alice 得到了 m, 它与初始文档完全一致。 然后, Alice 就可以论证仅有 Bob 能够签署这个文档,基于如下理由:
- 无论是谁签署这个报文,都必定在计算签名 KB-(m) 过程中使用了 KB- 这个私钥、使KB+(KB-(m)) =m。
- 知道KB- 这个私钥的人只有Bob。 我们知道公钥KB+,但对得知私钥 KB- 的信息没有帮助。 因此,知道私钥的人首当其冲就是 Bob。 (注意到此处假设 Bob 没有把私钥泄露给任何人,也没有人从Bob处窃取到)
注意到下列问题是重要的:如果源文档m被修改过,比如改成了另一个文档 m',则Bob 对 m 的签名对m'无效,因为KB+(KB- (m)) 不等于m'。 因此我们看到数字签名也提供报文完整性,使得接收方验证该报文未被篡改,同时也验证了该报文的源。
用加密进行数据签名的缺点是,加密和解密的计算代价昂贵。更有效的方法是将散列函数引人数字签名。散列算法取一个任意长的报文m, 计算生成对应该报文的一个固定长度的字符串,表示为H(m)。 先使用散列函数, 然后Bob 对报文的散列值签名而不是对报文本身签名,即 Bob计算KB-(H (m))。 因为 H(m) 通常比报文 m 小得多,所以生成数字签名所需要的计算量大为降低。
Bob 向 Alice 发送一个报文,下图提供了生成数字签名的操作过程的概览。 Bob 让他的初始长报文通过一个散列函数。 然后他用自己的私钥对得到的散列进行数字签名。 明文形式的初始报文连同已经数字签名的报文(从此以后可称为数字签名)一道被发送给Alice。

下图提供了鉴别报文完整性的操作过程的概览。 Alice先把发送方的公钥应用于已经数字签名的报文获得一个散列结果。 然后她再把该散列函数应用于明文报文以得到第二个散列结果。 如果这两个散列匹配,则 Alice 可以确信报文的完整性及其发送方。

公钥认证
数字签名的一个重要应用是公钥认证 (public key certification) , 即证实一个公钥属于某个特定的实体。 公钥认证用在许多流行的安全网络协议中,包括IPsec和 SSL。
为了深入理解这个问题,我们考虑一个因特网商务版本的经典的"比萨恶作剧"。 假定Alice 正在从事比萨派送业务,从因特网上接受订单。 Bob 是一个爱吃比萨的人,他向Alice 发送了一份包含其家庭地址和他希望的比萨类型的明文报文。 Bob在这个报文中也包含一个数字签名(即对原始明文报文先通过散列函数后进行签名),以向Alice证实他是该报文的真正来源。 为了验证这个数字签名, Alice 获得了 Bob 的公钥(也许从公钥服务器或通过电子邮件报文)并核对该数字签名。 通过这种方式, Alice确信是 Bob 而不是某些青少年恶作剧者下的比萨订单。

在聪明的Trudy 出现之前,这一切看起来进行得相当好。 如上图中所示, Trudy 沉溺于一场恶作剧中。 Trudy 向 Alice 发送一个报文,在这个报文中她说她是 Bob, 给出了Bob 家的地址并订购了一个比萨。 在这个报文中,也包含了她 (Trudy) 的公钥,Alice 自然地认为它就是 Bob 的公钥。 Trudy 也附加了一个数字签名,但这是用她自己 (Trudy)的私钥生成的。 在收到该报文后, Alice就会用Trudy 的公钥 (Alice认为它是 Bob 的公钥)来解密该数字签名,并得到结论:这个明文报文确实是由 Bob生成的。 而当外送人员带着具有意大利辣香肠和凤尾鱼的比萨到达Bob家时,他会感到非常惊讶!
从这个例子我们看到,要使公钥密码有用, 需要能够证实你具有的公钥实际上就是与你要进行通信的实体(人员、 路由器、 浏览器等)的公钥。例如,当 Alice与 Bob通信时,她需要证实接收到的那个公钥确实就是Bob 的公钥。将公钥与特定实体绑定通常是由认证中心(Certification Authority, CA) 完成的。 CA的职责就是使识别和发行证书合法化。 CA具有下列作用:
- CA 证实一个实体(一个人、一台路由器等)的真实身份。 如何进行认证并没有强制的过程。 当与一个CA打交道时, 一方必须信任这个CA能够执行适当的严格身份验证。 例如,如果Trudy走进名为Fly-by-Night 的认证中心并只是宣称"我是Alice" , 就可以得到该机构颁发的与Alice 的身份相关联的证书的话,则人们不会对Fly-by-Night认证中心所签发的公钥证书有太多的信任。 你对与公钥相关联的身份的信任程度,仅能达到你对CA及其身份验证技术的信任程度。
- 一旦 CA验证了某个实体的身份,这个CA会生成一个将其身份和实体的公钥绑定起来的证书 (certificate) 。 这个证书包含这个公钥和公钥所有者全局唯一的身份标识信息。 由 CA对这个证书进行数字签名。 这些步骤如下图所示

国际电信联盟 (International Telecommunication Union, ITU ) 和 IETF 都研发了用于CA 的系列标准。 ITU X. 509 规定了证书的鉴别服务以
及特定语法。 [ RFC 1422] 描述了安全因特网电子邮件所用的基于CA 的密钥管理。 它和X.509兼容、但比X.509 增加了密钥管理体系结构的创建过程和约定内容。 表中显示了一份证书中的某些重要字段,具体资料可自行查阅。

端点鉴别
端点鉴别 (end-point authenlieation) 就是一个实体经过计算机网络向另一个实体证明其身份的过程,例如一个人向某个电子邮件服务器证明其身份。 作为人类,我们通过多种方式互相鉴别:见面时我们互相识别对方的面容,打电话时我们分辨对方的声音,海关的检查官员通过护照上的照片对我们进行鉴别。
在本节中,我们讨论经网络通信的双方如何能够鉴别彼此。 此处我们重点关注当通信实际发生时鉴别"活动的"实体。一个具体的例子是一个用户向某电子邮件服务器鉴别他或她自已。 这与证明某点接收到的报文确实来自声称的发送方稍有不同。当经网络进行鉴别时,通信各方不能依靠生物信息比如外表、声波纹等进行身份鉴别。 我们会在后面的实例研究中看到,诸如路由器、客户/服务器进程等网络元素通常必须相互鉴别。 此处,鉴别应当在报文和数据交换的基础上,作为某鉴别协议 (authentication protocol ) 的一部分独立完成。 鉴别协议通常在两个通信实体运行其他协议(例如,可靠数据传输协议、路由选择信息交换协议或电子邮件协议)之前运行。 鉴别协议首先建立相互满意的各方的标识;仅当鉴别完成之后,各方才继续下面的工作。
我们逐步阐释各种版本的鉴别协议。我们将称为ap (authentication protocol) ,并随着我们学习的深入指出各个版本的漏洞。 我们假设 Alice 要向 Bob 鉴别她自己的身份。
鉴别协议 ap1.0
也许我们能够想象出的最简单的鉴别协议就是: Alice 直接发送一个报文给 Bob, 说她就是 Alice。 这个协议的缺陷是明显的,即 Bob 无法判断发送报文"我是AIice" 的人确实就是 Alice 例如, Trudy (入侵者)也可以发送这样的报文。
鉴别协议 ap2.0
如果Alice 有一个总是用于通信的周知网络地址(如一个IP地址),则 Bob 能够试图通过验证携带鉴别报文的IP数据报的源地址是否与 Alice 的周知 IP 地址相匹配来进行鉴别。 在这种情况下, Alice 就可被鉴别了。 这可能阻止对网络一无所知的人假冒 Alice, 但是它却不能阻止决定学习本书的学生或许多其他人!
根据我们学习的网络层和数据链路层的知识,我们就会知道做下列事情并不困难(例如,如果一个人能够访问操作系统代码并能构建自己的操作系统内核 比如Linux和许多其他免费可用的操作系统):生成一个IP数据报,并在IP数据报中填入我们希望的任意源地址(比如Alice 的周知 IP 地址),再通过链路层协议把生成的数据报发送到第一跳路由器。此后,具有不正确源地址的数据报就会忠实地向 Bob转发。 这种方法显示在图中,它是IP 哄骗的一种形式。 如果Trudy 的第一跳路由器被设置为只转发包含Trudy 的IP 源地址的数据报,就可以避免 IP 哄骗。 然而,这一措施并未得到广泛采用或强制实施,Bob 可能被欺骗。

鉴别协议 ap3.0
进行鉴别的一种经典方法是使用秘密口令。 口令是鉴别者和被鉴别者之间的一个共享秘密。 Gmail、 Telnet、 FTP和许多其他服务使用口令鉴别。 在协议ap3.0 中, Alice 因此向 Bob 发送其秘密口令,如图所示
由于口令的广泛使用,我们也许猜想协议 ap3.0 相当安全。 如果这样想,我们就错了!这里的安全性缺陷相当明显:如果Trudy 窃听了 Alice 的通信,则可得到Alice 的口令。 为了使你认识到这种可能性,考虑这样的事实,当你Telnet 到另一个机器上并登录时,登录口令未加密就发送到了Telnet 服务器。 连接到 Telnet 客户或服务器 LAN 的某个人都可能嗅探 (读并存储)在局域网上传输的所有数据分组,并因此窃取到该注册口令。 实际上,这是一种窃取口令的周知方法。 这样的威胁显然是真实存在的,所以协议ap3.0 明显也不可行。

鉴别协议 ap3. 1
我们完善协议ap3.0 的下一个想法自然就是加密口令了。 通过加密口令,我们能够防止Trudy 得知 Alice 的口令。 如果我们假定 Alice 和 Bob 共享一个对称秘密密钥 KA-B, 则Alice 可以加密口令,并向 Bob发送其识别报文"我是 Alice" 和加密的口令。 Bob 则解密口令,如果口令正确则鉴别了Alice。 因为Alice不仅知道口令,而且知道用于加密口令的共享秘密密钥值, Bob可以鉴别 Alice 的身份。 我们称这个协议为ap3. 1。
尽管协议ap3. 1 确实防止了 Trudy 得知 Alice 的口令,但Bob 受制于回放攻击 (playback attack) : Trudy 只需窃听 Alice 的通信、并记录下该
口令的加密版本,并向Bob 回放该口令的加密版本,以假装她就是Alice。 协议ap3. 1 中加密口令的使用,并未使它比协议ap3.0 的局面有明显改观。
鉴别协议 ap4.0
ap3.1的失败的情况是因为 Bob不能区分Alice 的初始鉴别报文和后来入侵者回放的 Alice 的初始鉴别报文所致。 也就是说, Bob 无法判断Alice 是否还活跃(即当前是否还在连接的另一端),或他接收到的报文是否就是前面鉴别Alice的回放(重放攻击)。 观察力极怪的读者会记起TCP的三次握手协议需要处理相同的问题,如果接收的SYN 报文段来自较早连接的一个SYN 报文段的旧副本(重新传输)的话, TCP连接的服务器一侧不会接受该连接。 TCP服务器一侧如何解决"判断客户是否真正还活跃"的问题呢? 它选择一个很长时间内都不会再次使用的初始序号,然后把这个序号发给客户,然后等待客户以包含这个序号的ACK报文段来响应。 此处我们能够为鉴别目的采用同样的思路。
不重数 (nonce) 是在一个协议的生存期中只使用一次的数。 也就是说, 一旦某协议使用了一个不重数,就永远不会再使用那个数字了。 协议 ap4.0 以如下方式使用一个不重数:
- Alice 向 Bob 发送报文"我是 Alice" 。
- Bob 选择一个不重数R, 然后把这个值发送给Alice。
- Alice 使用她与 Bob 共享的对称秘密密钥 KA-B来加密这个不重数,然后把加密的不重数KA-B® 发回给 Bob。 与在协议 ap3. 1 中一样,由于 Alice 知道 KA-8并用它加密一个值,就使得Bob知道收到的报文是由 Alice 产生的。 这个不重数用于确定Alice是活跃的。
- Bob 解密接收到的报文。 如果解密得到的不重数等于他发送给 Alice 的那个不重数,则可鉴别Alice 的身份。
通过使用这个在生存期中只出现一次的值R, 然后核对返回的值KA-B®, Bob 能够确定两点: Alice 是她所声称的那个人 (因为她知道加密R 所需的秘密密钥), Alice 是活跃的(因为她已经加密了 Bob 刚刚产生的不重数R)。
不重数和对称密钥密码体制的使用形成了 ap4.0 的基础。一个自然的问题是,我们是否能够使用不重数和公开密钥密码体制(而不是对称密钥密码体制)来解决鉴别问题?书中并没有给出讨论,而是放在了习题,此处贴出习题。

安全电子邮件
在前面的各节中,我们分析了网络安全中的基本问题,包括对称密钥密码体制和公开密钥密码体制、端点鉴别、 密钥分发、 报文完整性和数字签名。 我们现在着手研究如何使用这些工具在因特网中提供安全性。
有趣的是,为因特网协议栈上面4层的任一层提供安全性服务是可能的。 当为某一特定的应用层协议提供安全性时,则使用这一协议的应用程序将能得到一种或多种安全服务,诸如机密性、 鉴别或完整性。 为某一运输层协议提供安全性时,则所有使用这一协议的应用程序都可以得到该运输层协议所提供安全性服务。 在基于主机到主机的网络层提供安全性时, 则所有运输层报文段(当然也包括所有应用层数据) 都可以得到该网络层所提供的安全服务。 当基于一条链路提供安全性时, 则经过这个链路传输的所有帧中的数据都得到了该链路提供的安全性服务。
在后续小节中,我们考察了如何在应用层、运输层、网络层和数据链路层中使用这些安全性工具。 为了与本书的整体框架保持一致,我们从协议栈的顶层开始,讨论在应用层的安全性。 我们的方法是使用特定的应用程序如电子邮件,作为应用层安全性的一个学习案例。 然后我们沿协议栈向下,分析SSL协议(它在运输层提供安全性)、 IPsec 协议(它在网络层提供安全性),以及IEEE 802. 11 无线局域网协议的安全性。
你可能会感到奇怪:为什么要在因特网的多个层次上提供安全性功能呢?仅在网络层提供安全性功能并加以实施还不足够吗?对这个问题有两个答案。 首先,尽管可以通过加密数据报中的所有数据(即所有的运输层报文段),以及通过鉴别所有数据报的源IP地址,在网络层能够提供"地毯式覆盖"安全性,但是却并不能提供用户级的安全性。 例如,一个商业站点不能依赖lP层安全性来鉴别一个在该站点购买商品的顾客。 因此,此处除了较低层的地毯式覆盖安全性外,还需要更高层的安全性功能。 第二,在协议栈的较高层上部署新的因特网服务(包括安全性服务)通常较为容易。 而等待在网络层上广泛地部署安全性,可能还需要未来若干年才能解决,许多应用程序的开发者在他们中意的应用程序中引入安全性功能。 一个典型的例子就是PGP(Pretty Good Privacy) , 它提供了安全电子邮件。 由于只需要客户和服务器应用程序代码, PGP 是第一个在因特网上得到广泛应用的安全性技术。
安全电子邮件
我们现在使用前面的密码学原则来生成一个安全电子邮件系统。 我们以递进的方式来产生这个高层设计,每一步引入一些新安全性服务。 当设计安全电子邮件系统时, 我们设想一下Alice 发送一个电子邮件报文给 Bob, 而Trudy试图入侵的情况。在做出为 Alice 和 Bob设计一个安全电子邮件系统的努力之前,我们应当首先考虑他们最为希望的安全特性是什么。 重中之重是机密性。 Alice 或 Bob都不希望Trudy 阅读到 Alice 所发送的电子邮件报文。 Alice 和 Bob 最希望在该电子邮件系统中看到的第二种特性是具备发送方鉴别。 特别是,当Bob收到这样的报文"I don't love you anymore. I never want lo see you again. Formerly yours , Alice ( 我不再爱你了 。 我再也不想看到你了。 Alice)" 时, Bob 要确定这个报文确实来自 Alice, 而非 Trudy 发送的。 另外,这两个情人需要的另一种特性是报文完整性,也就是说,确保 Alice所发的报文在发送给Bob 的过程中没有被改变。 最后,电子邮件系统应当提供接收方鉴别;即Alice 希望确定她的确正在向 Bob发信,而不是向假冒 Bob 的其他人(如Trudy) 发信。
因此我们从处理最为关注的机密性开始。 提供机密性的最直接方式是Alice使用对称密钥技术(如DES或AES) 加密所要传输的报文,而 Bob则在接收时对报文解密。 如果对称密钥足够长,且仅有 Alice 和 Bob 拥有该密钥, 则其他人(包括Trudy) 要想读懂这条报文极为困难。 尽管这种方法直截了当,但因为仅有Alice 和 Bob具有该密钥的副本,这使得分发对称密钥非常困难 。 因此我们自然就考虑用其他方法(例如使用RSA)。 在公开密钥方法中, Bob使得他的公钥为公众所用 (例如,从一台公钥服务器或其个人网页上得到), Alice用 Bob 的公钥加密她的报文,然后向 Bob 的电子邮件地址发送该加密报文。 当 Bob接收到这个报文时,只需用他的私钥即可解密之。 假定Alice 确定得到的公钥是 Bob 的公钥,这种方法是提供所希望的机密性的极好方法。 然而,存在的一个问题是公开密钥加密的效率相对低下,尤其对于长报文更是如此。
为了克服效率问题,我们利用了会话密钥。 具体来说:1.Alice选择一个随机对称会话密钥 Ks;2.用这个随机对称会话密钥加密她的报文 m; 3.用 Bob 的公钥KB+加密这个随机对称会话密钥; 4.级联该加密的报文和加密的对称密钥以形成一个包; 4.向 Bob 的电子邮件地址发送这个包。 这些过程显示在下图1中(在这张图1和下一张图2中,带圈的 + 表示级联,带圈的 - 表示级联的分解)。 当 Bob 接收到这个包时:1.他使用其私钥KB-得到对称密钥Ks;2.使用这个对称密钥Ks解密报文m。

设计完提供机密性的安全电子邮件系统后,现在我们设计另一个可以提供发送方鉴别和报文完整性的系统。 我们暂且假设Alice 和 Bob 目前不关心机密性 ,只关心发送方鉴别和报文完整性。 为了完成这个任务,我们使用数字签名和报文摘要。 具体说来: 1.Alice 对她要发送的报文 m 应用一个散列函数H (例如 MD5), 从而得到一个报文摘要; 2.用她的私钥 KA- 对散列函数的结果(即报文摘要)进行签名,从而得到一个数字签名; 3.把初始报文(未加密)和该数字签名级联起来生成一个包; 4.向 Bob 的电子邮件地址发送这个包。 当 Bob接收到这个包时: 1.他将Alice 的公钥KA+应用到被签名的报文摘要上; 2.将公钥解开得到的结果 与 对初始报文进行散列得到的值 进行比较。
在下图2中阐述了这些步骤。 如果这两个结果相同,则 Bob 完全可以确信这个报文来自 Alice且未被篡改。

现在我们考虑设计一个提供机密性、发送方鉴别和报文完整性的电子邮件系统。 这可以通过把上方两张图中的过程结合起来而实现。此处我们按顺序将两张图,称作图1图2。 Alice 首先生成一个预备包,它与图2中的包完全相同,其中包含她的初始报文和该报文数字签名过的散列。 然后Alice把这个预备包看作一个报文,将这个包按照 图1发送方的步骤发送这个新报文。 Alice 所做的这些步骤如下图所示。 当 Bob 接收到这个包后,他首先应用图1中他这一侧的步骤,然后再应用图2 中他这一侧的步骤。 应当明确这一设计的目标是提供机密性、发送方鉴别和报文完整性。 注意到在这一方案中, Alice两次使用了公开密钥密码: 一次用了她的私钥,另一次用了 Bob 的公钥。 类似地, Bob也两次使用了公开密钥密码: 一次用了他的私钥, 一次用了 Alice 的公钥。

上图所示的安全电子邮件系统可能在大多数情况下都能为大多数电子邮件用户提供满意的安全性。 但是仍有一个重要的问题没有解决。 图 中的设计要求 Alice 获得 Bob 的公钥,也要求 Bob 获得 Alice 的公钥。 但这些公钥的分发并不是一个小问题。 例如,Trudy 可能假冒 Bob, 发给 Alice 她自己的公钥,并告诉 Alice 这个公钥是 Bob 的公钥,使得Trudy 就能接收到 Alice 发给Bob 的报文。 如我们所学,安全地分发公钥的一种常用方法是通过CA验证该公钥
PGP(简要介绍)
PGP (Pretty Good Privacy) 是电子邮件加密方案的一个范例 。 在公共领域中有各种版本的 PGP可供使用;PGP的设计在本质上文中所示的设计相同。 PGP软件的不同版本使用 MD5 或使用 SHA来计算报文摘要;使用CAST、三重DES 或IDEA进行对称密钥加密;使用 RSA 进行公开密钥加密。
安装PGP 时,软件为用户产生一个公开密钥对。 该公钥能被张贴到用户的网站上或放置在某台公钥服务器上。 私钥则使用用户口令进行保护。 用户每次访问私钥时都要输入这个口令。 PGP允许用户选择是否对报文进行数字签名、 加密报文,或同时进行数字签名和加密。
PGP 也提供了一种公钥认证机制,但是这种机制与更为传统的 CA 差异很大。 PGP公钥由一个可信Web验证。 当 Alice 相信一个密钥/用户名对确实匹配时,她自己就可以验证这一密钥/用户名对。 此外, PGP 允许Alice 为她所信任的用户鉴别更多密钥提供担保,一些PGP用户通过保持密钥签署方 (key-signing party) 互相签署对方的密钥。 用户实际走到一起,交换公钥,并用自己的私钥对对方的公钥签名来互相验证密钥。
参考目录
书籍:《计算机网络:自顶向下方法(第七版)》