程序员社区

https的加密原理-SSL+TLS

一、密码学的原则

密码技术使得发送方可以伪装数据,使入侵者不能从截取到的数据中获得任何信息。当然,接收方必须能够从伪装的数据中恢复出初始数据。下图说明了一些重要的术语:
在这里插入图片描述

现在假设Alice要向Bob发送一个报文。Alice报文的最初形式被称为明文。Alice使用加密算法加密其明文报文,生成的加密报文被称为密文,该密文对任何入侵者看起来是不可懂的。有趣的是在许多现代密码系统中,包括因特网上所使用的那些,加密技术本身是已知的,即公开发行的、标准化的和任何人都可使用的,即使对潜在的入侵者也是如此。显然,如果任何人都知道数据编码的方法,则一定有一些秘密信息可以阻止入侵者解密被传输的数据。这些秘密信息就是密钥。

在上图中,Alice提供了一个密钥

K

A

K_A

KA,它是一串数字或字符,作为加密算法的输入。加密算法以密钥和明文报文m为输入,生成的密文作为输出。用符号

K

A

(

m

)

K_A(m)

KA(m)表示明问报文m的密文形式。使用密钥

K

A

K_A

KA的实际加密算法显然与上下文有关。类似地,Bob将为解密算法提供密钥

K

B

K_B

KB,将密文和Bob的密钥作为输入,输出初始明文。

在对称密钥系统中,Alice和Bob的密钥是相同的并且是秘密的。在公开密钥系统中,使用一对密钥:一个密钥为Bob和Alice俩人所知(实际上为全世界所知),另一个密钥只有Bob或Alice知道(而不是双方都知道)。接下来更为详细的介绍对称密钥系统和公钥系统。

1.1 对称密钥密码体制

所有的密码算法都涉及用一种东西替换另一种东西的思想,例如,取明文的一部分进行计算,替换适当的密文以生成加密的密文。
(待补充/453)

1.2 公开密钥加密

对称密钥的一个困难是双方必须就共享密钥达成一致;但是这样做的前提是需要通信(可假定是安全的)。可能是双方首先会面,人为协商确定密钥,此后才能进行加密通信。但是,在网络世界中,通信各方之间可能从未见过面,也不会在网络以外的任何地方交谈。此时通信双方需要能够在没有预先商定的共享密钥的条件下进行加密通信。在1976年,Diffie和Hellman论证了一个解决这个问题的算法,开创了如今的公开密钥密码系统的发展之路。

公开密钥密码的使用在概念上相当简单。假设Alice和Bob通信。如下图所示:
在这里插入图片描述

此时Alice和Bob并未共享一个密钥(如同在对称密钥系统情况下),而Bob(Alice报文的接收方)则有两个密钥,一个是世界上的任何人(包括入侵者Trudy)都可得到的公钥,另一个是只有Bob知道的私钥。我们使用符号

K

B

+

K_B^+

KB+

K

B

K_B^-

KB来分别表示Bob的公钥和私钥。为了与Bob通信,Alice首先取得Bob的公钥,然后用这个公钥和一个众所周知的(例如,已标准化的)加密算法,加密她要传递给Bob的报文m;即Alice计算

K

B

+

(

m

)

K_B^+(m)

KB+(m)。Bob接收到Alice的加密报文后,用其私钥和一个众所周知的(例如,已标准化)的解密算法解密Alice的加密报文,即Bob计算

K

B

(

K

B

+

(

m

)

)

K_B^-(K_B^+(m))

KB(KB+(m))。后面我们将看到,存在着可以选择公钥和私钥的加密/解密算法和技术,使得

K

B

(

K

B

+

(

m

)

)

=

m

K_B^-(K_B^+(m))=m

KB(KB+(m))=m;也就是说,用Bob的公钥

K

B

+

K_B^+

KB+加密报文m(得到

K

B

+

(

m

)

K_B^+(m)

KB+(m)),然后再用Bob的私钥

K

B

K_B^-

KB解密报文的密文形式(就是计算

K

B

(

K

B

+

(

m

)

)

K_B^-(K_B^+(m))

KB(KB+(m)))就能够得到最初的明文m。用这种方法,Alice可以使用Bob公开可用的密钥给Bob发送机密信息,而他们任一方都无需分发任何密钥!接下来我们也可以看到,公钥和私钥机密相互交换同样能够得到不寻常的结果,即

K

B

(

K

B

+

(

m

)

)

=

K

B

+

(

K

B

(

m

)

)

=

m

K_B^-(K_B^+(m))=K_B^+(K_B^-(m))=m

KB(KB+(m))=KB+(KB(m))=m
(待补充/458)

二、报文完整性和数字签名

在这节中将讨论两个相关的主题:数字签名和端点鉴别。

再次使用Alice和Bob来定义报文完整性问题。假定Bob接收到一个报文(这可能已经加密或可能是明文),并且他认为这个报文是由Alice发送的,为了鉴别这个报文,Bob需要证实:

  • 该报文确实源自Alice
  • 该报文在到Bob的途中没有被篡改

2.1 密码散列函数

如下图所示,散列函数以m为输入,计算得到一个称为散列的固定长度的字符串H(m)
在这里插入图片描述
密码散列函数要求具有这样的性质:找到任意两个不同的报文x和y使得H(x)=H(y),在计算上是不可能的: 不严格地说,这种性质就意味着入侵者在计算上不可能用其他报文替换由散列函数保护的报文。这就是说,如果(m, H(m))是报文和由发送方生成的报文散列的话,则入侵者不可能伪造另一个报文y的内容,使得该报文具有与原报文相同的散列值。

2.2 报文鉴别码

接下来看下将如何执行报文完整性:

  1. Alice生成报文m并计算散列H(m)(例如使用SHA-1)
  2. Alice则将H(m)附加到报文m上,生成一个拓展报文(m,H(m)),并将该扩展报文发给Bob
  3. Bob接收到一个扩展报文(m, h)并计算H(m)。如果H(m)=h,Bob得到结论,一切正常

这种方式存在明显缺陷。Trudy能够生成虚假报文m’,在其中声称她就是Alice,计算H(m’)并发送给Bob(m’, H(m’))。当Bob接收到该报文,一切将在步骤3中核对通过,并且Bob无法猜出这种不轨的行为。

为了执行报文完整性,除了使用密码散列函数,Alice和Bob将需要共享秘密s,这个共享的秘密只不过是一个比特串,它被称为鉴别密钥。使用这个共享秘密,报文完整性能够执行如下:

  1. Alice生成报文m,用s级联m以生成m+s,并计算散列H(m+s)(例如使用SHA-1)。H(m+s)被称为报文鉴别码(Message Authentication Code,MAC)。
  2. Alice则将MAC附加到报文m上,生成拓展报文(m,H(m+s)),并将该扩展报文发送给Bob
  3. Bob接收到一个拓展报文(m,h),由于知道s,计算出报文鉴别码H(m+s)。如果H(m+s)=h,Bob得到结论:一切正常。

下图显示了上述过程的总结。需要注意这里的MAC(表示报文鉴别码)与用于数据链路层中的MAC(表示媒体访问控制)是不一样的。
在这里插入图片描述

MAC的一个优良特点是它不要求一种加密算法。使用一个MAC,实体能够鉴别它们相互发送的报文,而不必在完整性过程中综合进复杂的加密过程。

多年来已经提出了若干种对MAC的不同标准。目前最为流行的标准是HMAC,它能够与MD5或SHA-1一道使用。

2.3 数字签名

在数字领域,人们通常需要指出一个文件的所有者或创作者,或者表明某人认可一个文件内容。数字签名就是在数字领域实现这种目标的一种密码技术。

正如人手签名一样,数字签名也应当以可鉴别的、不可伪造的方式进行。这就是说,必须能够证明由某个人在一个文档上的签名确实是由该人签署的(该签名必须是可证实的),且只有那个人能够签署那个文件(该签名无法伪造)。

Bob具有公钥和私钥,这两种密钥对Bob均为独特的。因此,公钥密钥是一种提供数字签名的优秀候选者,我们接下来研究一下这是怎样完成的。

假设Bob要以数字方式签署一个文档m。我们能够想象这个文档是Bob打算签署并发送的一个文件或一个报文。如下图所示:
在这里插入图片描述
为了签署这个文档,Bob直接使用他的私钥

K

B

K_B^-

KB计算

K

B

(

m

)

K_B^-(m)

KB(m)。乍一看,会感觉很奇怪,Bob怎么会用他的私钥(在上面的介绍中,我们用私钥解密用其公钥加密的报文)签署文档。但是回想加密和解密都只不过是数学运算而已(RSA中所作的e或d指数幂运算),并且Bob的目的不是弄乱或掩盖文档的内容,而只是要以可鉴别的、不可伪造的方式签署这个文档。Bob对文档m签名之后所得的文档就是

K

B

(

m

)

K_B^-(m)

KB(m)

数字签名

K

B

(

m

)

K_B^-(m)

KB(m)是否满足了可鉴别的、不可伪造的需求?假设Alice有m和

K

B

(

m

)

K_B^-(m)

KB(m)。她要证明Bob确实签署过这个文档,他就是唯一能够签署该文档的人。Alice持有Bob的公钥

K

B

+

K_B^+

KB+,并把它用于Bob的数字签名

K

B

(

m

)

K_B^-(m)

KB(m)上,从而得到了文档m。也就是说,Alice计算

K

B

+

(

K

B

(

m

)

)

K_B^+(K_B^-(m))

KB+(KB(m)),最终可以得到m,它与初始文档完全一致。然后,Alice就可以论证仅有Bob能够签署这个文档,基于如下理由:

  • 无论是谁签署这个报文,都必定在计算

    K

    B

    (

    m

    )

    K_B^-(m)

    KB(m)过程中使用了

    K

    B

    K_B^-

    KB这个私钥,使得

    K

    B

    +

    (

    K

    B

    (

    m

    )

    )

    K_B^+(K_B^-(m))

    KB+(KB(m))

  • 知道

    K

    B

    K_B^-

    KB这个私钥的唯一人只有Bob。从上面对RSA的讨论中可知,知道公钥

    K

    B

    +

    K_B^+

    KB+无助于得知私钥

    K

    B

    K_B^-

    KB的信息。因此,知道私钥

    K

    B

    K_B^-

    KB的人才是生成密钥对

    K

    B

    ,

    K

    B

    +

    K_B^-,K_B^+

    KB,KB+的人,而这个人就是Bob

注意到下列问题也是重要的,如果源文档m被修改过,比如改成了另一个文档m‘,则Bob对m生成的签名对m’无效,因为

K

B

+

(

K

B

(

m

)

)

K_B^+(K_B^-(m))

KB+(KB(m))不等于m‘。因此我们的数字签名也提供完整性,使得接收方验证该报文未被篡改,同时也验证了该报文的源。

对用加密进行数据签名的担心是,加密和解密的计算代价昂贵。给定加解密的开销,通过完全加密/解密对数据签名是杀鸡用牛刀。更有效的方法是将散列函数引入数字签名。上节中说过,一种散列算法取一个任意长的报文m,计算生成该报文的一个固定长度的数据“指纹”,表示为H(m)。使用散列函数,Bob对报文的散列签名而不是对报文本身签名,即Bob计算

K

B

(

H

(

m

)

)

K_B^-(H(m))

KB(H(m))。因为H(m)通常比报文m小得多,所以生成数字签名所需要的计算耗费大为降低。

下图表示了Bob向Alice发送一个报文的情况下,生成一个数字签名的操作过程的概览:
在这里插入图片描述
Bob让他的初始长报文通过一个散列函数。然后他用自己的私钥对得到的散列进行数字签名。明文形式的初始报文连同已经数字签名的报文摘要(从此以后可称为数字签名)一道被发给Alice。

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

接下来简要地将数字签名与MAC进行比较,尽管它们有类似之处,但也有重要的微妙差异。数字签名和MAC都以一个报文(或一个文档)开始。为了从该报文中生成一个MAC,我们为该报文附加一个鉴别密钥,然后取得该结果的散列。注意到在生成MAC过程中既不涉及公开密钥加密,也不涉及对称密钥加密。为了生成一个数字签名,我们首先取得该报文的散列,然后用我们的私钥加密该报文(密码是公钥)。因此,数字签名是一种“技术含量更高”的技术,因为它需要一个如后面描述的、具有认证中心支撑的公钥基础设施(PKI)。

2.3.1 公钥认证

数字签名的一个重要应用是公钥认证,即证实一个公钥属于某个特定的实体。公钥认证被用于许多流行的安全网络协议中,包括IPsec和SSL。

为了理解公钥认证的作用,考虑一个经典的“披萨恶作剧”。假定Alice正在从事披萨派送业务,从因特网上接收订单。Bob向Alice发送了一份包含其家庭地址和他希望的披萨类型的明文报文。Bob在这个报文中也包含了一个数字签名(即对原始明文报文的签名的散列),以向Alice证实他是该报文的真正来源。为了验证这个数字签名,Alice获得了Bob的公钥(也许从公钥服务器或通过电子邮件报文)并核对该数字签名。通过这种方式,Alice确信是Bob而不是某些青少年恶作剧者下的披萨订单。

假设恶作剧者Trudy向Alice发送一个报文,在这个报文中她说她是Bob,给出了Bob家的地址并订购了一个披萨。在这个报文中,她也包括了她(Trudy)的公钥,虽然Alice自然地假定它就是Bob的公钥。Trudy也附加了一个签名,但是这是用她自己(Trudy)的私钥生成的。在收到该报文后,Alice就会利用Trudy的公钥(Alice认为这是Bob的公钥)来解密该数字签名,并得到结论:这个报文确实是Bob生成的。而当外卖人员带着披萨来到Bob家时,他会感到非常惊讶。整个过程如下所示:
在这里插入图片描述
从这个例子我们看到,要使公钥密码有用,需要能够证实你具有的公钥实际上就是与你要进行通信的实体(人员、路由器、浏览器等)的公钥。例如,当Alice与Bob使用公钥密码进行通信时,她需要证实她假定是Bob的那个公钥确实就是Bob的公钥。

将公钥与特定实体绑定通常都是由认证中心(Certification Authority,CA)完成,CA的职责就是使识别和发行证书合法化。CA具有下列作用:

  1. CA证实一个实体(一个人、一台路由器等)的真实身份。如何进行认证并没有强制的过程。当与一个CA打交道时,一方必须信任这个CA能够执行适当的严格身份验证。例如,如果Trudy可以走进一个证书权威机构并只是宣称“我是Alice”就可以得到该机构颁发的与Alice的身份相关联证书的话,则人们不会对这个机构所颁发的公钥证书有太多的信任。
  2. 一旦CA验证了某个实体的身份,这个CA会生成一个把其身份和实体的公钥绑定起来的证书(certificate)。这个证书包含这个公钥和公钥所有者全局唯一的身份标识信息(例如,一个人的名字或一个IP地址)。由CA对这个证书进行数字签名。这些步骤如下图所示(Bob获得一份来自CA的证书):
    在这里插入图片描述

我们现在来看怎样使用认证来对抗“披萨订购”中的恶作剧者(如Trudy)和其他意外情况。当Bob下订单的同时,他也发送了其CA签署的证书。Alice使用CA的公钥来核对Bob的证书的合法性并提取Bob的公钥。

三、使TCP连接安全:SSL

接下来我们将介绍密码技术如何用安全性服务加强TCP,TCP的这种强化版本通常被称为安全套接字层(Secure Socket Layer,SSL)。SSL版本3的一个稍加修改的版本被称为运输层安全性(Transport Layer Security,TLS)。

3.1 SSL体系结构

SSL为TCP提供可靠的端到端安全服务,SSL不是简单的单个协议而是两层协议,如下图所示:
在这里插入图片描述
SSL记录协议(SSL Record Protocol)为高层协议提供基本的安全服务,特别是为Web客户端/服务器交互提供传送服务的HTTP协议可以在上层访问SSL。SSL协议上定义了三个高层协议:握手协议、修改密码规范协议和警报协议。这些SSL上层协议用于对SSL交换进行管理。

SSL中包含两个重要概念:SSL会话和SSL连接,在规范中定义如下:

  • 连接:连接是提供合适服务类型的一种传输(OSI层次模型中定义)。对SSL来说,连接表示的是对等网络关系,且连接是短暂的,每个连接与一个会话相关。
  • 会话:SSL会话是一个客户端和服务器间的关联,会话是通过握手协议创建的,定义了一组多个连接共享的密码安全参数。会话可用于减少为每次连接建立安全参数的昂贵协商费用。

在多方会谈中(如客户端和服务器间HTTP应用),需要多个安全连接,从理论上来说,可以在多方之间同时发生会话,但还没有在实际中使用。

每个会话实际上与多种状态相关,一旦会话建立,则进入针对读和写(如接收和发送)的当前操作状态。另外,在握手协议中,会创建读挂起状态和写挂起状态。在握手协议成功完成后,挂起状态成为当前状态。

一个会话状态由以下参数定义(参见SSL规范):

  • 会话标志:服务器用于标志为活动或恢复的会话状态的一个随机字节序列。
    待补充416

3.2 SSL记录协议

SSL记录协议为SSL连接提供如下两种服务。

  • 保密性:握手协议定义了加密SSL载荷的传统加密共享密钥
  • 消息完整性:握手协议也定义了生成消息认证代码(MAC)的共享密钥

下图展示了SSL记录协议的整个操作过程。记录协议接收一个要传送的应用信息,将其段分为块,压缩(可选),加上MAC,加密,再加上一个SSL头,将得到的最终数据单元放入一个TCP段中。接收的数据被解密、验证、解压、重组后,再传递给高层用户。
在这里插入图片描述
第一步是分段,每个上层消息被分成若干小于或等于

2

14

2^{14}

214字节的段;接着进行可选择压缩,压缩必须采用无损压缩方法,并且增加长度不能超过1024字节。再SSLv3和当前的TLS中,没有指定压缩算法,所以默认的压缩算法为空。

接着对压缩数据计算其消息认证码MAC。为此,需要使用共享密钥,其计算方式如下:
在这里插入图片描述
其中:
在这里插入图片描述
接下来,将压缩消息和MAC用对称加密算法加密。加密对内容增加长度不能超过1024字节,以便整个长度不能超过

2

14

+

2048

2^{14}+2048

214+2048。以下加密算法是允许的。Fortezza可被用于智能卡加密模式。

对流加密而言,压缩消息和MAC一起被加密。注意,MAC在加密之前计算,然后将MAC和明文或压缩后的明文一起加密。

对分组加密而言,填充应在MAC之后、加密之前进行。填充的格式是一定长度的填充字节后跟1字节的填充长度。整个填充域的长度是使得总长度(明文+MAC+填充域的长度)为规定的加密分组长度整数倍的最小长度。例如,明文(或如果使用了压缩则为压缩文本)长度为58字节,MAC长度为20字节(使用SHA-1),使用分组长度为8字节的加密算法(如DES),则加上填充长度域的1字节总共79字节,为了达到8的整数倍,则需要添加1字节的填充。

SSL记录协议的最后一步是加上一个由如下域组成的SSL头:

  • 内容类型(8位):封装段使用的高层协议
  • 主版本号(8位):表明SSL使用的主版本号,如SSLv3的值为3
  • 从版本号(8位):表明SSL使用的从版本号,如SSLv3的值为0
  • 压缩长度(16位):明文段(如果使用了压缩,则为压缩段)的字节长度,最大值为

    2

    14

    +

    2048

    2^{14}+2048

    214+2048

已经定义的内容类型包括修改密码规范、警报、握手和应用数据。接下来讨论前三个类型。注意,在各种应用中使用SSL并没有什么限制,它们提供的数据内容对SSL来说是不透明的。

下图是一个SSL记录格式的例子:
在这里插入图片描述

3.5 握手协议

SSL的复杂性主要来自于握手协议。此协议允许客户端和服务端互相认证、协商加密和MAC算法,保护数据使用的密钥通过SSL记录传送。握手协议在传递应用数据之前使用。

握手协议由客户端和服务器交换的一系列消息组成,这些消息的格式如下表所示:

消息类型 参数
hello_request
client_hello 版本号、随机数、会话标志、密码组、压缩方法
server_hello 版本号、随机数、会话标志、密码组、压缩方法
certificate X.509v3证书链
server_key_exchange 参数、签名
certificate_request 类型、认证机构
server_done
certificate_verify 签名
client_key_exchange 参数、签名
finished Hash值

下图表明了在客户端与服务器之间建立逻辑连接的初始交换。此交换由四个阶段组成:
在这里插入图片描述

3.5.1 阶段1:建立安全功能

此阶段用于建立初始的逻辑连接,并建立与之相关联的安全功能,客户端发起这个交换,发送具有如下参数的client_hello消息:

  • 版本:客户端所支持的最高SSL版本。
  • 随机数:由客户端生成的随机数据结构,用32位时间戳和一个安全随机数生成器生成的28字节随机数组成。这些值作为随机数,在密钥交换时防止重放攻击。
  • 会话标志:一个变长的会话标志。非0值意味着客户端想更新现有连接的参数,或为此会话创建一个新的连接;0值意味着客户端想在新会话上创建一个新的连接。
  • 密码组:按优先级的降序排列的、客户端支持的密码算法列表。表的每个元素定义了一个密钥交换算法和一个密码说明。
  • 压缩方法:一个客户端支持的压缩方法列表。

客户端发出消息client_hello后,会等待包含与消息client_hello参数相同的server_hello message消息的到来。对server_hello消息而言,应用了如下惯例:版本域中包含的是客户端支持的最低版本号和服务器支持的最高版本号。随机数域是由服务器生成的,与客户端的随机数域互相独立。如果客户端会话标志非0,则服务器使用与之相同的值,否则,服务器的会话标志域包含新对话的值。密码组域包含着服务器从客户端所给的密码组中选出的密码组。压缩域包含的是服务器从客户端所给出的压缩方法中选出的压缩方法。

密码组参数的第一个元素是密钥交换方法(如传统加密密钥和MAC交换的方法)。支持下述密钥交换方法:
在这里插入图片描述

3.5.2 阶段2:服务器认证和密钥交换

如果需要认证,则服务器开始发送其证书:消息包含一个或一组X.509证书。除匿名Diffie-Hellman方法外,其他密钥交换方法均需要证书消息certificate message。注意,如果使用固定Diffie-Hellman,此证书消息将由于包含了服务器Diffie-Hellman公钥参数而作为服务器的密钥交换消息。

接着,如果需要,可以发送服务器密钥交换信息(server_key_exchange message)。在以下两种情况下,不需要此消息:

SSL协议有三个特性:

  1. 保密:在握手协议中定义了会话密钥后,所有的消息都被加密
  2. 鉴别:可选的客户端认证,和强制的服务器端认证
  3. 完整性:传送的消息包括消息完整性检查(使用MAC)

为了理解SSL的需求,接下来看下某典型的因特网商业的场景:Bob在浏览Web网页,到达了Alice公司的站点,这个站点正在出售香水。Alice公司站点显示了一个表格,假定Bob可以在该表格中输入香水的类型和所希望的数量、他的地址和他的支付卡号等信息。Bob输入这些信息,点击“提交”,就期待收到所购买的香水;他也期待着在他的下一次支付卡报表中收到对所购买物品的支付信息。所有这一切听起来不错,但是如果不采取安全措施,Bob也许会有一些意外。

  • 如果没有使用机密性(保密),一个入侵者可能截取Bob的订单并得到他的支付卡信息。这个入侵者则可以用Bob的费用来购买商品。
  • 如果没有使用完整性,入侵者可能修改Bob的定单,让他购买比希望瓶数多10倍的香水
  • 最后,如果没有使用服务器鉴别,这个显示Alice公司著名徽标的服务器实际上是由Trudy维护的一个站点,Trudy正在假冒Alice公司。当Trudy收到Bob的订单后,可能拿了Bob的钱一走了之。或者Trudy可能充当一个身份窃贼,收集Bob的名字、地址和信用卡号。

SSL通过采用机密性、数据完整性、服务器鉴别和客户鉴别来强化TCP,就可以解决这些问题。

SSL经常用来为发生在HTTP之上的事务提供安全性,并且它能被应用于运行在TCP之上的任何应用程序。SSL提供了一个简单的具有套接字的应用编程接口(API),该接口类似于TCP的API。当一个应用程序要使用SSL时,它包括了SSL类/库。

如下图所示,尽管SSL技术上位于应用层中,但从研发者的角度看,它是一个提供TCP服务的运输协议,而这里的TCP服务用安全性服务加强了。
在这里插入图片描述
SSL的工作原理:

  • 握手协议
  • 记录协议
  • 警报协议

3.1 握手协议

握手协议是客户机和服务器用SSL连接通信时使用的第一个子协议,握手协议包括客户机与服务器之间的一系列消息。该协议允许服务器和客户机互相验证,协商加密和MAC算法以及保密密钥,用来保护在SSL记录中发送的数据。握手协议是在应用数据的数据传输之前使用的。

每个握手协议包含以下三个字段:

  • Type:表示十种消息类型之一
  • Length:表示小时长度字节数
  • Content:与消息相关的参数

握手协议共有四个阶段:
在这里插入图片描述

3.1.1 阶段一 建立安全能力

SSL握手的第一阶段启动逻辑连接,首先确保这个连接的安全能力。客户机先向服务器发出client hello消息并等待服务器响应,随后服务器向客户机返回server hello消息,对client hello消息中的信息进行确认。

客户端发送client hello信息,其中包括:

  • 客户端可以支持的SSL最高版本号
  • 一个用于生成主秘密的32字节的随机数
  • 一个确定会话的会话ID
  • 一个客户端可以支持的密码套件列表
    密码套件的格式:每个套件都以“SSL”开头,紧跟着的是密钥交换算法。用“With”这个词把密钥交换算法、加密算法、散列算法分开,例如:SSL_DHE_RSA_WITH_DES_CBC_SHA,表示把DHE_RSA(带有RSA数字签名的暂时Diffie-HellMan)定义为密钥交换算法;把DES_CBC定义为加密算法;把SHA定义为散列算法。
  • 一个客户端可以支持的压缩算法列表

服务端用server hello信息应答客户,包括下列内容:

  • 一个SSL版本号,取客户端支持的最高版本号和服务端支持的最高版本号中的较低者。
  • 一个用于生成主秘密的32字节的随机数。(客户端一个、服务端一个)
  • 会话ID
  • 从客户端的密码套件列表中选择一个密码套件。
  • 从客户端的压缩方法的列表中选择一个压缩方法

这个阶段后,客户端和服务端都知道了下列内容:

  • SSL版本
  • 密钥交换、信息验证和加密算法
  • 压缩方法
  • 有关密钥生成的两个随机数

3.1.2 阶段二 服务器鉴别与密钥交换

服务器启动SSL握手第二阶段,是本阶段所有消息的唯一发送方,客户机是所有消息的唯一接收方。该阶段分为四步:

  1. 证书:服务器将数字证书到根CA整个链发给客户端,使客户端能用服务器证书中的服务器公钥认证服务器
  2. 服务器密钥交换(可选):这里视密钥交换算法而定
  3. 证书请求:服务端可能会要求客户自身进行验证
  4. 服务器握手完成:第二阶段的结束,第三阶段开始的信号。

在这里插入图片描述
上面的阶段1(证书)和阶段2(服务器密钥交换)是基于密钥交换方法的。在SSL中密钥交换算法有6种:无效(没有密钥交换)、RSA、匿名Diffie-Hellman、暂时Diffie-Hellman、固定Diffie-Hellman、Fortezza。在阶段一过程客户端与服务端协商的过程中已经确定了使用哪种密钥交换算法。如果协商过程中确定使用RSA交换密钥,那么过程如下图:
在这里插入图片描述
这个方法中,服务器在它的第一个信息中,发送了RSA加密/解密公钥证书。不过,因为预备主密码是由

3.1宏观描述

接下来从描述一个简化的SSL版本开始,这将使我们从宏观上理解SSL的工作原理和工作过程。我们将这个简化的SSL称为“类SSL”。类SSL具有三个阶段:握手、密钥导出和数据传输。我们在下面描述针对一个客户(Bob)和一个服务器(Alice)之间的通信会话的这三个阶段,其中Alice具有私钥/公钥对和她的身份与其公钥绑定的证书。

3.1.1 握手

在握手阶段,Bob需要:

  1. 与Alice创建一条TCP连接
  2. 验证Alice是真实的Alice
  3. 发送给Alice一个主密钥,Bob和Alice持用该主密钥生成SSL会话所需的所有对称密钥。

如下图所示:
在这里插入图片描述

注意到一旦创建了TCP连接,Bob就向Alice发送一个hello报文。Alice则用她的证书进行响应,证书中包含了她的公钥。因为该证书已被某CA证实过,Bob明白无误地知道该公钥属于Alice。然后,Bob产生一个主密钥(MS)(该MS将仅用于这个SSL会话),用Alice的公钥加密该MS以生成加密的主密钥(EMS),并将该EMS发送给Alice。Alice用她的私钥解密该EMS从而得到该MS。在这个阶段后,Bob和Alice(而无别的人)均知道了用于这次SSL会话的主密钥。

3.1.2 密钥导出

从原则上讲,MS此时已由Bob和Alice共享,它能够用作所有后继加密和数据完整性检查的对称会话密钥。然而,对于Alice和Bob每人而言,使用不同的密码密钥,并且对于加密和完整性检查也使用不同的密钥,通常认为更为安全。因此,Alice和Bob都使用MS生成四个密钥:

  • E

    B

    E_B

    EB:用于从Bob发送到Alice的数据的会话加密密钥

  • M

    B

    M_B

    MB:用于从Bob发送到Alice的数据的会话MAC密钥

  • E

    A

    E_A

    EA:用于从Alice发送到Bob的数据的会话加密密钥

  • M

    A

    M_A

    MA:用于从Alice发送到Bob的数据的会话MAC密钥

Alice和Bob每人都从MS生成四个密钥。这能够通过直接将该MS分成四个密钥来实现(但在真正的SSL中更为复杂一些)。在密钥导出阶段结束时,Alice和Bob都有了4个密钥。其中的两个加密密钥将用于加密数据;两个MAC密钥将用于验证数据的完整性。

3.1.3. 数据传输

既然Alice和Bob共享相同的四个会话密钥,他们就能经TCP连接开始发送安全的数据。因为TCP是一种字节流协议,一种自然的方法是用SSL在传输中加密应用数据,然后将加密的数据在传输中传给TCP。但是如果我们真的这样做,我们将用于完整性检查的MAC置于何处呢?我们无疑不希望等到TCP会话结束时才验证所有Bob数据的完整性,Bob数据的发送要经历整个会话。为了解决这个问题,SSL将数据流分割成记录,对每个记录附加一个MAC用于完整性检查,然后加密该“记录+MAC”。为了产生这个MAC,Bob将数据连同密钥

M

B

M_B

MB放入一个散列函数中。为了加密“记录+MAC”这个包,Bob使用他的会话加密密钥

E

B

E_B

EB。然后这个加密的包将传递给TCP经因特网传输。

虽然这种方法几经周折,但它为整个报文流提供数据完整性时仍未达到无懈可击。特别是,假设Trudy是一个“中间人”,并且有在Alice和Bob之间发送的TCP报文段流中插入、删除和代替报文段的能力。例如,Trudy能够俘获由Bob发送的两个报文段,颠倒这两个报文段的次序,调整TCP报文段的序号(这些未被加密),然后将这两个次序翻转的报文段发送给Alice。假定每个TCP报文段正好封装了一个记录,我们现在看看Alice将如何处理这些报文段:

  1. 在Alice端运行的TCP将认为一切正常,将这两个记录传递给SSL子层
  2. 在Alice端的SSL将解密这两个记录
  3. 在Alice端的SSL将使用在每个记录中的MAC来验证这两个记录的数据完整性。
  4. 然后SSL将解密的两条记录的字节流传递给应用层;但是Alie收到的完整字节流由于记录的颠倒而次序不正确。

对该问题的解决方案是使用序号。SSL采用如下的方式。Bob维护一个序号计数器,计数器开始为0,Bob每发送的一个SSL记录它都增加1.Bob并不实际在记录中包括一个序号,但当他计算MAC时,他把该序号包括在MAC的计算中。所以,该MAC现在是数据加MAC密钥

M

B

M_B

MB加当前序号的散列。Alice跟踪Bob的序号,通过在MAC的计算中包括适当的序号,使她验证一条记录的数据完整性。SSL序号的使用组织了Trudy执行诸如重排序或重放报文段等中间人攻击。

3.1.4 SSL记录

SSL记录如下图所示:
在这里插入图片描述
该记录由类型字段、版本字段、长度字段、数据字段和MAC字段组成。注意到前三个字段是不加密的。类型字段指出了该字段是握手报文还是包含应用数据的报文。它也用于关闭SSL连接,如下面所讨论。在接收端的SSL使用长度字段以从到达的TCP字节流中提取SSL记录。版本字段是自解释的。

3.2 更完整的描述

3.2.1 SSL握手

SSL并不强制Alice和Bob使用一种特定的对称密钥算法、一种特定的公钥算法或一种特定的MAC。相反,SSL允许Alice和Bob在握手阶段在SSL会话开始时就密码算法取得一致。此外,在握手阶段,Alice和Bob彼此发送不重数,该数被用于会话密钥(

E

B

,

M

B

,

E

A

,

M

A

E_B,M_B,E_A,M_A

EB,MB,EA,MA)的生成中。真正的SSL握手的步骤如下:

  1. 客户发送它支持的密码算法的列表,连同一个客户的不重数
  2. 从该列表中,服务器选择一种对称算法(例如AES)、一种公钥算法(例如具有特定密钥长度的RSA)和一种MAC算法。它把它的选择以及证书和一个服务器不重数返回给客户
  3. 客户验证该证书,提取服务器的公钥,生成一个前主密钥(Pre-Master Secret,PMS),用服务器的公钥加密该PMS,并将加密的PMS发送给服务器
  4. 使用相同的密钥导出函数(像SSL标准定义的那样),客户和服务器独立地从PMS和不重数中计算出主密钥(Master Secret,MS)。然后该MS被切片以生成两个密码和两个MAC密钥。此外,当选择的对称密码应用于CBC(例如3DES或AES),则两个初始化向量(Initialization Vector,IV)也从该MS获得,这两个IV分别用于该连接的两端。自此以后,客户和服务器之间发送的所有报文均被加密和鉴别(使用MAC)
  5. 客户发送所有握手报文的一个MAC。
  6. 服务器发送所有握手报文的一个MAC

最后两个步骤使握手免受篡改危害。为了理解这一点,观察在第一步中,客户通常提供一个算法列表,其中有些算法强,有些算法弱。因为这些加密算法和密钥还没有被协商好,所以算法那的这张列表以明文形式发送。Trudy作为中间人,能够从列表中删除较强的算法,迫使客户选择一种较弱的算法。为了防止这种篡改攻击,在步骤5中客户发送一个级联它已发送和接收的所有握手报文的MAC。服务器能够比较这个MAC与它已接收和发送的握手报文段MAC。如果有不一致,服务器能够终止该连接。类似地,服务器发送一个它已经看到的握手报文的MAC,允许客户检查不一致性。

在步骤1和步骤2中存在不重数的原因:
考虑下列连接重放攻击,假设Trudy嗅探了Alice和Bob之间的所有报文。第二天,Trudy冒充Bob并向Alice发送正好是前一天Bob向Alice发送的相同的报文序列。如果Alice没有使用不重数,她将以前一天Bob向Alice发送的完全相同的序列报文进行响应。Alice将不怀疑任何不规矩的事,因为她接收到的每个报文将通过完整性检查。如果Alice是一个电子商务服务器,她将认为Bob正在进行第二次采购(正好采购相同的东西)。在另一方面,在协议中包括了一个不重数,Alice将对每个TCP会话发送不同的不重数,使得这两天的加密密钥不同。因此,当Alice接收到来自Trudy重放的SSL记录时,该记录将无法通过完整性检查,并且假冒的电子商务事件将不会成功。总而言之,在SSL中,不重数用于防御“连接重放”,而序号用于防御在一个进行的会话中重放个别分组。

3.2.2 连接关闭

在某个时刻,Bob或Alice将要终止SSL会话。一个方法是让Bob通过直接终止底层的TCP连接来结束该SSL会话,这就是说,通过让Bob向Alice发送一个TCP FIN报文段。但是这种幼稚设计为截断攻击创造了条件,Trudy再一次介入一个进行中的SSL会话中,并用TCP FIN过早地结束了该会话。如果Trudy这样做的话,Alice将会认为她收到了Bob的所有数据,而实际上她仅收到了其中的一部分。对于这个问题的解决方法是,在类型字段中指出该记录是否是用于终止该SSL会话的。(尽管SSL类型是以明文形式发送的,但在接收方使用了记录的MAC对它进行了鉴别)。通过包括这样一个字段,如果Alice在收到一个关闭SSL记录之前突然收到了一个TCP FIN,她可能知道正在进行着某些耍花招的事情。

四、TLS

在这里插入图片描述
图中第一个蓝色往返是TCP的握手过程,之后两次橙色的往返,我们可以叫做TLS的握手,握手过程如下:

  • client1:TLS版本号+所支持加密套件列表+希望使用的TLS选项
  • server1:选择一个客户端的加密套件+自己的公钥+自己的证书+希望使用的TLS选项+(要求客户端证书)
  • client2:(自己的证书)+使用服务器公钥和协商的加密套件加密一个对称密钥(自己生成的一个随机值)
  • server2:使用私钥解密出对称密钥(随机值)后,发送加密的finish消息,表明完成握手。

要注意公钥和私钥的加密和解密耗时耗费资源,HTTPS为了追求性能,又要保证安全,采用了共享密钥加密和公开密钥加密混合的方法进行报文传输。具体来说,HTTPS采用公私钥的机制传输共享密钥,当共享密钥安全到达服务端后往后的数据都采用该密钥进行加密解密。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » https的加密原理-SSL+TLS

一个分享Java & Python知识的社区