TLS/SLL 是现在网络安全通信比较重要的一环,通过一些列的 key 交换和 key 生成,最终确立加密通道的整个流程。众所周知,TLS/SSL 耗费的时间也是挺可观的,相对于 TCP 的3次 RTT 来说,如果加上 TLS/SSL, 则总的 RTT 时间至少为 4 次。虽然看起来很多,但如果相对于现在的网络环境来说,大概也就每次 20~30ms,这样算下来,估计也就 100ms 左右。这样的时间差还是可以忍受的,不过,这里还没算入 DNS 解析,这个暂时不考虑。而且,TLS/SSL 生成的 sessionkey 如果在有效期内的话,那么这个时间就可以完全忽略掉了。不多说了,我们直接来看下 TLS/SSL 的基本内容。 TLS 算法TLS/SSL 其实就是通过非对称加密,生成对称加密的 sessionkey 的过程。对称加密的算法无外乎就 AES,或者使用 Cipher/Decipher 模块。而非对称加密常用的就是 RSA,不过也有使用 Diffie-Hellman (迪菲)。但,较安全性来说,DH 要高一些。因为,RSA 在生成 sessionkey 时,最后是由 browser 生成,然后通过 public key 加密后传给 server 的,这样存在一定的问题是,如果 hacker 得到了 private key,那么,他可以全程监控流量,然后使用 private key 进行解密,那么可想而知,sessionkey 也就暴露了。 但对于 DH 来说,它机制的不同点在于,sessionkey 不会通过网络传输,而是在两端独立生成的。ok~ 这就涉及到两个 key 的一致性问题。DH 还有一个机制,即,前向安全性(perfect forward secrecy--PFS):server 端的 private key,不能用来代替以前任何一把的 sessionkey,所以,也无法破解以前任何一次的 session 内容。每次连接,DH 都会重新生成一个 key,并且当该次 session 结束时,丢弃它。不过,这并不是很大的问题,因为 DH 能很快的生成 key。因为它耗费在网络上的时间相比于 RSA 来说少了一半。可以从下图简单了解 DH 的加密算法:
简单来说,两边通过一次的信息交换,完成了密钥生成。因为 sessionkey 是独立放在两端的,为了达到一致性,每次连接时,DH 都需要重新协商生成 sessionkey。现在有个问题是: 为什么一定要有 session key,他存在的意义是什么? sessionkey 用途TLS/SSL 其实就是通过非对称加密,生成对称加密的 session key 的过程 那 session key 主要又干了什么呢? 首先,我们要先明确,session key 是用来进行对称加密的,这种加密方式主要使用到的是 AES 加密算法。这不同于 Elliptic Curve Diffie-Hellman (ECDH) 这种非对称加密算法。两者其实都可以用来对信息进行加密,但由于算法内部的实现机理不同,他们所用的时间也是不一样的。基本上是,ECDH 所用的时间是 AES 的 3 倍。 你可以自行测试一下: openssl speed ecdh
openssl speed aesok,上面大概简述了 TLS/SSL 所用到的算法。接下来,我们来了解一下,具体 TLS/SSL 密钥交换的过程。 TLS/SLL 过程在详述过程之前,我们需要了解一下,在过程中会出现的内容。
相信大家对这张图已经很熟悉了:
不过,上面不是说了有两种不同的非对称加密方式吗? RSA & DH? 那为什么图只是一个嘞? ok,实际上这图没错,他并没有把传输的内容是什么写出来,这很关键。而两种算法也是在传输内容上区分开的,基本的过程是完全一样的。根据 wiki 的解释,我们大概能知道整个传输过程需要的内容。
上面主要是根据 RSA 加密方式来讲解的。因为 RSA 才会在 TLS/SSL 过程中,将 pre-master secret 显示的进行传输,这样的结果有可能造成,hacker 拿到了 private key 那么他也可以生成一模一样的 sessionKey。即,该次连接的安全性就没了。 接下来,我们主要讲解一下另外一种加密方式 DH。它和 RSA 的主要区别就是,到底传不传 pre-master secret。RSA 传而 DH 不传。 根据 cloudflare 的讲解可以清楚的了解到两者的区别: 这是 RSA 的传输方式,基本过程如上述。
而 DH 具体区别在下图:
这里先补充一下 DH 算法的知识。因为,pre-master secret 就是根据这个生成的。DH 基本过程也不算太难,详情可以参考 wiki 。 它主要运用到的公式就是:
为了防止在 DH 参数交换时,数据过大,DH 使用的是取模数的方式,这样就能限制传输的值永远在 [1,p-1]。这里,先说明一下 DH 算法的基本条件:
基本流程就是:
我们只要把上图的 DH parameter 替换为相对应的 X/Y 即可。而最后的 Z 就是我们想要的 Premaster secret。 之后,就和 RSA 加密算法一致,加上两边的 random-num 生成 sessionKey。通过,我们常常称 DH 也叫作 而 RSA 和 DH 两者之间的具体的区别就在于:RSA 会将 premaster secret 显示的传输,这样有可能会造成私钥泄露引起的安全问题。而 DH 不会将 premaster secret 显示的传输。 TLS/SSL 中的基本概念上面内容大概讲清楚了基本的 TLS/SSL 的加密过程。不过,其中,还有很多其他的小细节,比如 SNI,ALPN,Forward Secrey。 接下来,我们主要将这些细节将一下,因为他们其实也很重要。 Forward SecreyFS(Forward Secrey) 主要是针对 private key 进行描述了。如果你的 private key 能够用来破解以前通信的 session 内容,比如,通过 private key 破解你的 premaster secret ,得到了 sessionKey,就可以解密传输内容了。这种情况就是 non-forward-secrey。那如何做到 FS 呢? 很简单,上文也已经提到过了,使用 DH 加密方式即可。因为,最后生成的 sessionKey 和 private key 并没有直接关系,premaster secret 是通过 简单的说就是,如果你想要启用 FS,那么你应该使用的是 DH 加密方式,而放弃 RSA。不过,由于历史原因(TLS 版本问题),RSA 现在还算是主流的加密方式。但,DH 也凭借他 ALPNALPN 全称是 Application Layer Protocol Negotiation(应用层协议协商机制)。看到应用层,程序员们应该都能反应出 OSI 7层网络协议。在应用层中,HTTP 协议应该是重点。不过,由于 HTTP 版本的问题,以及现在 HTTP2 的流行,为了让 client-server 使用相同的协议而出现了 ALPN。ALPN 实际上是从 SPDY 中的 NPN 协议衍生出来的。不过,它们俩的机制正好相反。
总的来说,NPN 已经退出历史的舞台了。。。ALPN 现在是 IETF 指定的标准协议。ALPN 在 TLS 具体的过程是:
SNISNI 的全称为:Server Name Indication。该机制的提出的意义是,当有一个 server 同时处理了很多个 host 时。相当于,一个 IP 映射多个域名,但,由于证书只能对一个 3 级域名有效,所以,针对于多个 host 来说,server 为了能同时兼顾这些域名。一种简单的办法就是重定向到指定域名,如果都想支持的话,也行,掏钱自己多买几个证书 (真土豪)。如果,你很土豪的话,现在就有这样的情况,一个 IP 服务器下,搭载了支持多个域名的 server,并且每个域名都有合法的 CA 证书。那么,server 怎么判断,哪一个域名用哪一个证书呢?这时候,就需要用到 SNI。相当于在 TLS 阶段,将 host 一并发送过去,然后 server 就知道在 serverhello 阶段该返回啥证书了。 现在,有个问题,为什么一定要用 SNI 呢? 我们回想一下,这里我们仅仅只是建立 TCP + TLS 连接,客户端的一些内容,比如 hostname,我们并不能在 TCP 中获得。而,想要获得的话,就需要等到 HTTP 阶段,获得 client 传过来的 Session Resumption感觉能看到这里的人,应该都是闲的蛋疼的人。。。如果让我来看这篇文章,估计看几张图,我基本上就直接关网站了。因为,这实在是复杂。并且,上面说的只是协议上的复杂性,对于计算机来说,只需要记下每一次该发什么东西而已,但真正让 Computer 感到蛋疼的是,key 的计算。特别是 random key 和 premaster secret 动不动就是 32B,48B 的数据量。所以,为了真正减少计算机的工作量(实际上是 server),提出了 Session ID 和 Session Tickets,来将成功进行连接的 session 内容缓存起来。 Session IDSession ID 是 server 将上一次成功连接的 session 内容存在自己的硬盘里面。这里,就不涉及对 session data 的二次加密。基本的过程是:
那么相对于完全的 TLS/SSL 连接来说,这里只用到了一次 RTT。那么协议过程就变为了:
Session Ticket既然 Session ID 是为了解决网络时延和计算机性能问题,那么 Session Ticket 又干了什么呢? Session Ticket 和 Session ID 做的也是同样的事情,server 将最新一次的 sesion data 通过二次加密,在上一次握手结束时传递过去,然后 client 将传递过来的信息保存。 这样,利不利用缓存的 session data 这时,就取决于 client。如果该次的 session data 没有过期,那么 client 就会在 clientHello 阶段将该数据发送过去,server 接受到之后,便开始进行解密然后,双方生成 sessionKey,握手结束。 那 Session Ticket 和 Session ID 到底用哪一个呢? 这估计得看你的业务情况了,Session ID 注重的是节省性能,而损耗部分空间。Session Ticket 注重的是节省空间,而损耗部分性能。它们两者都能节省一次 RTT 时间,用谁,还是得看你的服务器的具体情况。 CA 证书详情前面大致说了 TLS/SSL 是怎样运作的,以及有哪些连接方法。相当于,学画一条线一样,我们现在只知道这条线该画多长,但还不知道,这条线从哪里画。所以,接下来,我们就需要来探讨一下,两端发生了什么。其实也不难,主要还是关于 CA 证书的存放和验证。server 端的很简单,就是把自己的 CA 证书发过来就 ok。但,client 验证这个证书是否可信,会有点复杂。 首先,证书颁发机构就那么一些,换句话理解就是,每个证书颁发机构,就代表着一张 CA 证书。但,现在市面上的 HTTPS 网站,辣么辣么多,难道他们都用同一张证书?难道他们都有一样的 pu/pr key? 那么 HTTPS 安全还有用吗? 所以,按照上面的推理,我们的网站上的 HTTPS 证书,肯定都是各不一样的。一般来说,有 3 种类型的证书: DV(Domain Validation),OV(Organization Validation),EV(Extended Validation)。均价按照顺序上升,所以,最便宜的就是 DV,这应该是我们勤劳的贫苦大众用得起的。它们之间具体的区别在于域名的支持上:
那我们的证书在芸芸证书中,是处于哪一个层级呢? 一般是三级。怎么体现的呢?
那这么多证书,我们用的是哪一个呢?当然是,最下面那个。因为每个证书并不是都被信任,所以客户端首先就要了解一下,你这个证书能否用来进行验证。如果不行的话,那么你这次连接就是不被信任的,就没有 CA 链式验证首先,什么叫做可信的证书呢? 我们先要明白一个道理,HTTPS 是先建立在人与人之间的相互信任上,然后才建立在机器与机器的相互信任上。假如,根证书 A 机构,恶意的将一个以前颁发过的证书,又给了另外一个 而验证的可行性,通常又跟机构的权威性有着极大的关系。它基本的验证过程简述就是(按照上面的层级):
如果上述任一步骤出现问题,那么该次 TLS/SSL 就不会进行,会回退。那么它们在询问的时候,会不会发送网络请求呢? 不会~ 因为,电脑在初始化时,会自带很多可信任的证书机构(即,Root CA),也就是我们刚刚提到的 VeriSign Class 3 的证书机构。以及,能够签发证书的二级机构(比较少)。到时候,浏览器会自动的根据数字签名来进行证书的验证。 CA 合法验证上面已经阐述了,CA 证书的合法性是自下而上的验证方式。那么它们具体验证协议是怎样的呢? 在说之前,我们先说几个概念:
CA 验证首先需要说一下它的颁发过程:
然后,验证过程就是根据这个来的:
而上面的三级证书层级,也是同样的道理,自上而下的找就 ok。当然,有时候为了验证的速度,会做一些缓存,这样就不必再进行验证了。所以,根据上面的描述,有童鞋可能会想到,能不能自签证书呢?反正,浏览器也是从本地找的。 当然可以, 具体的过程可以参考: 生成自己的 CA 证书 。 以前,在使用 Charles 和 Fiddler 的时候,一直在想,它们是怎么做到,将自己的证书,变成签发机构证书。
后来发现,它是把证书中的相关字段该成它的证书内容。不过,对于某些高级证书,还是会有一些问题,比如,wx.qq.com(微信的) 另外,为了证书的可靠性,提出了 证书的吊销现在有个问题,为什么证书有过期时间呢? 这同样是为了安全性,前面说过,如果你的证书发生了泄漏(实际上就是私钥)。那么,其他服务器就可以作为一个代理去拦截你的流量。这时候,由于过期的原因,可能一段时间后,中间恶意的服务器就没用了,另外,如果你发现了你遗失了证书,可以向颁发机构去挂失。 另外,还有一个原因是证书吊销的 证书的吊销有两种机制:CRL,OCSP CRLCRL(Certificate Revocation List),即,证书吊销列表。CA 机构会生成一个列表,列表里面是当前周期被吊销证书的序列号,当进行证书验证时,同样也会进行验证该项。如果,已经是吊销证书的话,那么该次 TLS/SSL 连接也会失败。 我们可以从证书信息中找到 CRL URI:
该协议虽然简单,但,缺陷还是比较多的。
OCSPOCSP(Online Certificate Status Protocol),即,在线证书状态协议。它通过在线请求的方式来进行验证,不需要下载整个 list,只需要将该证书的序列号发送给 CA 进行 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|