《HTTPS权威指南》-协议学习笔记

由《HTTPS权威指南》- SSL、TLS和密码学学习笔记知道了协议的用处,这里再贴一遍:
为什么需要协议
加密基元本身没有什么用,例如加密和散列算法。我们只有将这些元素组合成方案和协议才能满足复杂的安全需求。
实例场景:
Alice和Bob要通信。Mallory是个攻击者。
我们假设协议允许交换任意数量的消息。因为对称加密擅长对大量数据进行加密,所以选取我们最喜欢的AES算法来进行数据加密。使用AES,Alice和Bob可以安全的交换消息,Malloc看不到他们通信的内容。但是这还不够,因为Malloc还可以干其它事情,例如神不知鬼不觉的修改消息。为了解决这个问题,我们使用只有Alice和Bob知道的散列密钥计算每个消息的MAC,在发送消息的同时,也发送消息的MAC。这时Mallory再也不能修改消息了,然而他仍然可以丢弃或者重发任意消息。为了解决这个问题,我们扩展协议,为每条消息标记指定序号。最为重要的是,我们将序号作为MAC计算数据的一部分。如果发现序号出现空缺,就能知道消息丢了。如果发现序号重复,就检测重放攻击。为了得到最佳效果,我们使用某个特殊消息来标记会话结束。如果没有这个消息,Mallory能够悄悄的结束(截断)会话。如果所有措施以到位,Mallory最多只能做到阻止Alice和Bob与其他人通信。我们对此无能为力。
到目前为止,有一大块缺失:Alice和Bob如何协商得到需要的两个密钥(一个用于加密(AES的密钥),一个用于检测完整性(MAC的密钥)),同时还要当心Mallory?我们通过为协议添加两个步骤来解决这个问题:
使用公钥密码对会话进行身份验证。举个例子,Alice生成一个随机数,要求Bob对其签名以证明真的是他,Bob也要求Alice做同样的事情。
使用密钥交换方案对加密密钥进行秘密协商。举个例子,Alice可以生成所有密钥,使用Bob的公钥加密,再发送给Bob,这就是RSA密钥交换的工作方式。
最后我们协议完工时的状态是:
以握手阶段开始,包括身份验证和密钥交换
数据交换阶段,保存机密性和完整性
以关闭序列结束。
【《HTTPS权威指南》-协议学习笔记】站在宏观的角度看,我们的协议与SSL和TLS完成的工作相似。
这篇文章将描述TLS协议中的具体体现。
TLS定义了四个核心子协议:

  • handshake protocol: 握手协议(包括身份验证和密钥交换)
  • change cipher spec protocol: 密钥规格变更协议(会话恢复)
  • application data protocol: 应用数据协议(数据阶段,保证机密性和完整性)
  • alert protocol: 警报协议(包括关闭序列的警告)
记录协议
宏观上TLS以记录协议(record protocol)实现。
《HTTPS权威指南》-协议学习笔记
文章图片
屏幕快照 2016-12-19 22.42.58.png 加密基元和加密套件
TLS协议需要哪些加密基元?
握手过程中:
  • 身份验证:非对称加密,公钥加密,RSA
  • 密钥交换:RSA,支持前向保密的DH,ECDH等
传输过程中:
  • 加密算法:机密性的保证,例如AES,可有模式:CBC,ECB,GCM之类的,强度,128,256之类的。
  • 完整性的保证:例如MAC,PRF
以上基元和其它参数构成了密码套件,它可以精确定义如何实现安全,密码套件都倾向于使用较长的描述性名称,并且相当一致:
TLS_密钥交换_身份验证_WITH_密码_完整性保证

其中密码可写为:
算法_强度_模式

因此密码套件与下所示:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

表示:
以RSA公钥验证身份,使用ECDHE密钥交换,使用AES_128_GCM加密传输的数据,使用SHA256保证数据完整性。
握手协议的目的
在握手协议完成前,消息传输没有收到任何保护(从技术上讲,就是使用了TLS_NULL_WITH_NULL_NULL密码套件),一旦握手完成,就开始按协商取得的连接参数进行加密和完整性验证。
由上可以握手协议的目的有:
  • 协商取得连接参数
  • 验证身份
  • 交换密钥
  • 验证握手消息没被第三方修改
密钥交换
在TLS中,会话安全性取决于成为主密钥(master secret)的48字节共享密钥。密钥交换的目的是计算另一个值,即预主密钥(premaster secret),这个值是组成主密钥的来源。
TLS支持许多密钥交换算法,比如下表所示:
密钥交换 描述
dh_anon Diffie-Hellman(DH)密钥交换,未经身份验证
dhe_rsa 临时DH密钥交换,使用RSA身份验证
ecdh_anon 临时椭圆曲线DH(elliptic curve DH,ECDH)密钥交换,未经身份验证
ecdhe_rsa 临时ECDH密钥交换,使用RSA身份验证
ecdhe_ecdsa 临时ECDH密钥交换,使用RSA身份验证
使用哪一种密钥交换是由协商的套件所决定。一旦套件决定下来,两端都能了解按照哪种算法继续操作。
RSA密钥交换
交换方式:客户端生成预主密钥,使用服务器公钥对其加密,将其包含在ClientKeyExchange消息中,最后发送出去。服务器只需要使用私钥界面这条消息就能得到预主密钥。
攻击方式:对手可以制定长期行动,攻击者会记录所有加密的流量,耐心等待有朝一日可以得到密钥。比如,计算机能力的进步使暴力破解成为可能,也可以通过法律强制力、政治高压、贿赂或强行进入使用该密钥的服务器来取得密钥。只要密钥泄露,就可以解密之前的所有流量了。(因为从私钥可以很容易推出预主密钥,然后推出主密钥。)
Diffie-Hellman密钥交换
是一种密钥协定的协议,支持前向保密,诀窍是正向计算简单,逆向计算困难的数学函数,即使交换中的某些因子已被知晓,情况也是一样。最恰当的类比示例是混色:如果有两种颜色,那么狠容易将其混在一起得到第三种颜色,但是如果只有第三种颜色,很难确定究竟是哪两种颜色混合而成。
实现:DH密钥交换需要6个参数:其中两个(dh_p,dh_g)称为域参数,由服务器选定,协商过程中,客户端和服务器各自生成另外两个参数,相互发送其中一个参数(dh_Ys和dh_Yc)到对端,在经过计算,最终得到共享密钥。
握手协议分为3种:
  • 完整的握手,对服务器进行身份验证(单向验证)
  • 对客户端和服务器都进行身份验证(双向验证)
  • 恢复之前的会话采用的简单握手
单向验证
以下图片来自:SSL/TLS 握手过程详解
1、客户端开始新的握手(ClientHello),
  • 将自身支持的功能提交给服务器(支持的密码套件(Clipher Suites)列表,扩展(Extensions)里面支持的散列算法,是否支持心跳(添加连接保活功能,使DTLS(依赖于UDP之上)也能长连接)等)。
  • 生成随机数用来验证服务器,这个随机数在后面的摘要密钥和加密密钥的生成有关。

    Paste_Image.png
2、服务器选择连接参数,并返回一个随机数(ServerHello)
《HTTPS权威指南》-协议学习笔记
文章图片
Paste_Image.png 3、服务器发送证书链(Certificate)
《HTTPS权威指南》-协议学习笔记
文章图片
Paste_Image.png 4、根据连接参数中的密钥交换方式,发送生产主密钥的额外信息。(ServerKeyExchange)
《HTTPS权威指南》-协议学习笔记
文章图片
Paste_Image.png 5、服务器通知自己完成了协商过程。(ServerHelloDone)
《HTTPS权威指南》-协议学习笔记
文章图片
Paste_Image.png
6、客户端发送生成主密钥所需的额外信息(ClientKeyExchange:预主密钥)。
//主密钥生成函数PRF master_seret = PRF(pre_master_secret,"master secret", ClientHello.random+ServerHello.random)

7:客户端切换加密方式并通知服务器(change clipeher spec:告诉服务器,我下面发的信息都要加密了)。
8:客户端计算发送和接收到的握手消息的MAC并发送(finished:客户端发送第一条加密信息)。
9:服务器切换加密方式并通知客户端(change clipher spec:告诉客户端,我下面发的信息都要加密了)。
10:服务器计算发送和接收到的握手信息的MAC并发送(finished:服务器发送第一条加密信息)。
由上面可以看出,第1、2步Hello消息是用来协商取得连接,3-6步是用来验证身份和交换密钥,最后8和10步需要MAC是用来验证握手消息没被第三方修改。
以上握手流程图示:
《HTTPS权威指南》-协议学习笔记
文章图片
屏幕快照 2016-12-19 22.04.12.png 双向验证
只有已经经过身份验证的服务器才允许请求客户端身份验证。
与单向验证添加以下步骤:
1、服务器发送CertificateRequest消息请求客户端进行身份验证,消息中带有接受的证书的公钥和签名算法或者证书颁发机构列表。
2、客户端发送证书链给服务器Certificate。
3、客户端使用CertificateVerify消息证明自己拥有的私钥与之前发送的客户端证书中的公钥相对应。
图示如下:
《HTTPS权威指南》-协议学习笔记
文章图片
屏幕快照 2016-12-19 22.16.12.png 会话恢复
完整的握手协议非常复杂,需要很多握手消息和两次网络往返才能开始发送客户端应用数据。此外握手执行的密钥学操作通常需要密集的CPU处理。身份验证通常以客户端和服务器的证书验证来完成,需要更多的工作。这其中许多消耗都可以通过简短的握手方式节约下来。
最初的会话机制是再一次完整协商的连接断开时,客户端和服务器都会将会话的安全参数保存一段时间。
步骤:
  • 希望恢复先前会话的客户端将合适的会话ID放入ClientHello消息,然后提交
  • 服务器如果愿意恢复会话,就将相同的会话ID放入ServerHello消息返回
  • 服务器接着使用之前协商的主密钥生成一套新的密钥,再切换到加密模式,发送finished消息
  • 客户端收到会话以恢复的消息后,也进行相同的操作。
这样的结果是握手只需要一次网络往还。
图示:
《HTTPS权威指南》-协议学习笔记
文章图片
屏幕快照 2016-12-19 22.29.08.png 用来替代服务器会话缓存与恢复的方案:
会话票证(session ticker):除了所有的状态都保存在客户端(与HTTPCookie原理类似)之外,其消息流与服务器会话缓存一致
应用数据协议
记录层使用当前连接安全参数对这些信息进行打包、碎片整理和加密。
警报协议
以简单的方式告知对端通信出现异常,通常会携带close_notify异常,在连接关闭时使用。
关闭连接
关闭连接警报用以有序的方式关闭TLS连接。
步骤:
  • 一旦一端决定关闭连接,就会发送一个close_notify警报。
  • 另一端在接收到这个警告过后,会丢弃任何还未写出的数据,并发送自己的close_notify警告
  • 在警告之后到来的任何消息都将被忽略。
可以避免截断攻击,因为没有关闭协议,通信双方无法确认是遭受攻击还是通信结束。

    推荐阅读