由《HTTPS权威指南》- SSL、TLS和密码学学习笔记知道了协议的用处,这里再贴一遍:javascript
加密基元自己没有什么用,例如加密和散列算法。咱们只有将这些元素组合成方案和协议才能知足复杂的安全需求。java
实例场景:
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密钥交换的工做方式。安全
最后咱们协议完工时的状态是:
以握手阶段开始,包括身份验证和密钥交换
数据交换阶段,保存机密性和完整性
以关闭序列结束。服务器
站在宏观的角度看,咱们的协议与SSL和TLS完成的工做类似。网络
这篇文章将描述TLS协议中的具体体现。session
宏观上TLS以记录协议(record protocol)实现。并发
TLS协议须要哪些加密基元?
握手过程当中:app
传输过程当中:
以上基元和其它参数构成了密码套件,它能够精肯定义如何实现安全,密码套件都倾向于使用较长的描述性名称,而且至关一致:
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)到对端,在通过计算,最终获得共享密钥。
单向验证
如下图片来自:SSL/TLS 握手过程详解
一、客户端开始新的握手(ClientHello),
二、服务器选择链接参数,并返回一个随机数(ServerHello)
三、服务器发送证书链(Certificate)
四、根据链接参数中的密钥交换方式,发送生产主密钥的额外信息。(ServerKeyExchange)
五、服务器通知本身完成了协商过程。(ServerHelloDone)
//主密钥生成函数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:服务器发送第一条加密信息)。
由上面能够看出,第一、2步Hello消息是用来协商取得链接,3-6步是用来验证身份和交换密钥,最后8和10步须要MAC是用来验证握手消息没被第三方修改。
以上握手流程图示:
双向验证
只有已经通过身份验证的服务器才容许请求客户端身份验证。
与单向验证添加如下步骤:
一、服务器发送CertificateRequest消息请求客户端进行身份验证,消息中带有接受的证书的公钥和签名算法或者证书颁发机构列表。
二、客户端发送证书链给服务器Certificate。
三、客户端使用CertificateVerify消息证实本身拥有的私钥与以前发送的客户端证书中的公钥相对应。
图示以下:
会话恢复
完整的握手协议很是复杂,须要不少握手消息和两次网络往返才能开始发送客户端应用数据。此外握手执行的密钥学操做一般须要密集的CPU处理。身份验证一般以客户端和服务器的证书验证来完成,须要更多的工做。这其中许多消耗均可以经过简短的握手方式节约下来。
最初的会话机制是再一次完整协商的链接断开时,客户端和服务器都会将会话的安全参数保存一段时间。
步骤:
这样的结果是握手只须要一次网络往还。
图示:
用来替代服务器会话缓存与恢复的方案:
会话票证(session ticker):除了全部的状态都保存在客户端(与HTTPCookie原理相似)以外,其消息流与服务器会话缓存一致
记录层使用当前链接安全参数对这些信息进行打包、碎片整理和加密。
以简单的方式告知对端通讯出现异常,一般会携带close_notify异常,在链接关闭时使用。
关闭链接警报用以有序的方式关闭TLS链接。
步骤:
能够避免截断攻击,由于没有关闭协议,通讯双方没法确认是遭受攻击仍是通讯结束。
个人简书主页:www.jianshu.com/users/b92ab…