HTTP协议
用户访问网站,通常使用的是HTTP协议。HTTP协议传输的数据没有经过任何加密,是明文的。这些数据只要被黑客抓包到,就可以根据数据获取到用户信息,如用户登录时的用户名和密码。

HTTPS协议
既然明文传输有问题,那么你可能想到了加密方法。将数据加密后再传输,不就可以了吗?
没错,这就是HTTPS协议的目的。

HTTPS协议与HTTP协议的区别是,HTTP协议直接建立在TCP协议的基础上,但是HTTPS协议是在HTTP协议和TCP协议之间,增加了一层加密协议,即SSL/TSL协议。HTTPS就是通过这层协议来加密数据的。这样,数据通过SSL/TSL协议后,封装到TCP数据包中时,已经是加密的,即使被黑客获取,数据也不会被泄露。

SSL/TSL协议
SSL/TSL协议是啥
HTTPS离不开SSL/TSL协议。那么这个协议到底是啥呢?
SSL: Secure Sockets Layer。很久以前,网景公司意识到HTTP协议的不安全性,于是就设计出了SSL协议,用于对HTTP传输的数据进行加密。SSL协议已经很久不更新了,现在已被TSL协议替代。但是由于其开创性地位,并且当前仍被大多数浏览器所支持,SSL依旧是HTTPS的代名词。
TSL: Transport Layer Security。TSL是在SSL 3.0(SSL最后更新版本)的基础上发展起来的。因此,SSL是TSL的先驱。当前HTTPS使用的大多是TSL协议,也会有SSL3.0协议,不过浏览器都支持。TSL和SSL没有本质的区别,就像C/C++联合起来讲一样,TSL和SSL一般也联合起来讲,书写为:SSL/TSL协议。
SSL/TSL协议简述
SSL/TSL协议从简来讲的话,大致是下面几个流程:

客户端生成一个随机数 random-client,传到服务器端(Say Hello)
服务器端生成一个随机数 random-server,和着公钥,一起回馈给客户端(I got it)
客户端收到的东西原封不动,加上 premaster secret(通过 random-client、random-server 经过一定算法生成的东西),再一次送给服务器端,这次传过去的东西会使用公钥加密
服务器端先使用私钥解密,拿到 premaster secret,此时客户端和服务器端都拥有了三个要素:random-client、random-server 和 premaster secret
此时安全通道已经建立,以后的交流都会校检上面的三个要素通过算法算出的 session key
流程中几个关键点:
客户端生成的随机数
服务器生成的随机数
公钥
所为协议,即是一种约定,双方都要遵从。因此我们没必要死记硬背这个协议的流程,而是需要理解,这个协议中为何需要这些流程。这些流程中,某些流程是否多余?考虑是否充分?是否还需要补充其他流程?当然,我们知道,这个协议经过这么多年的发展,显然是很完备的,里面的流程不会冗余也不会缺少。下面我们需要通过几个问题,深入理解一下SSL/TSL协议。
几个问题
任何解决方案都是针对出现的问题而提出的。通过分析可能出现的问题,我们能大概理解这个协议中的部分含义。
怎么加密
上面讲了,HTTPS需要将数据进行加密后传输。那么问题是,数据应该怎样加密呢?
我们知道,当前在密码学中,主要的加密方法有两大分支:对称加密和非对称加密。既然我们还不知道使用哪种加密,不妨两种加密方法都试试。(对于对称加密和非对称加密不了解的同学,请先Google之,了解个大概先)

对称加密
对称加密的特点:
加密和解密使用的密钥是相同的
加密解密速度快,效率高
下面我们看看只使用对称加密算法会有什么问题:

如图所示,对称加密算法的核心是密钥。但是难点在于秘钥的传输和管理。客户端使用的密钥需要告诉服务器,这样服务器才能拿密钥来解密。但是密钥只能是明文传输,会被黑客窃取。这就相当于,给一把锁的同时,还给了一把开锁的钥匙,这是没有任何意义的。因此,只使用对称加密算法不可取。
非对称加密
非对称加密的特点:
客户端使用公钥加密。公钥是任何人都可以获取的
服务器只能使用对应的私钥解密。任何人没有私钥,都解密不了数据
计算量大,效率低。只适合加密少量数据。

可以看出,使用非对称加密算法,数据的安全性有了保证。但是加解密速度太慢,影响网站响应速度。因此,这种方法也不太可行。
非对称加密和对称加密联合使用
通过上面的分析,相信有些同学已经抓住了重点:
对称加密需要解决的是密钥传输问题。
非对称加密需要解决的是效率问题。
这样,能不能用非对称加密来解决对称加密的密钥传输问题,用对称加密解决非对称加密的效率问题。

如上图所示,客户端和服务端的数据交换使用对称加密算法进行加密,对称加密的密钥通过非对称加密传输。这样,非对称加密的数据量很少,只加密了一个密钥,效率不是问题。而数据是通过对称加密算法进行传输的,效率和安全性都有了保障。两全其美。
不过有个问题是,如何能保证对面给的公钥是可信的?万一有人给用户一个假的公钥,然后骗取了用户的密钥呢?这是一个可信性认证问题。
如何确认对方可信
举个简单的例子,方便理解这个问题:

如果出现上面这种情况,一个你不能确定身份的人跟你要钱,你会给吗?99%的人在确定对方身份之前是不会给的(剩下的1%是不差钱的)。
在工程中,这种欺骗行为叫做中间人攻击。实施攻击案例如下:

那么,如何判断对方的身份是否属实呢?通常情况下,对方会给你出示个证件来证明其身份。

但是,证件是可以伪造的,怎么能确定这个证件是真的?
首先,要明确一件事情,在这个人不可信的情况下,他提供的任何证据都是不可信的。
因此,这种情况下,就必须有一个权威的,大家都信任的第三方人或机构。如果这个人或机构能证明这个人可信,那么你就可以放心了。当然,第三方人或机构还需要充当一个担保的角色。如果证明有误,由第三方人或机构来赔偿。
试想,如果习大大担保说你可以给钱给对方,你还会犹豫吗?
这种可信的第三方机构,就是数字证书认证机构,简称:CA(Certificate Authority)
CA的认证过程如下图所示:

首先,网站会事先向CA机构申请证书。这个证书类似于身份证,是网站身份的象征。
当用户访问网站的时候,网站会把证书给用户。
用户的浏览器拿到证书后,浏览器会判断出证书是否可信。如果证书可信,可继续访问,否则,浏览器会有错误提示。用户当然可以无视警告继续访问,但风险是很大的。
那么,下一个问题就是,浏览器是如何判断证书是否可信的?这是证书认证问题。
如何认证证书
从上面我们知道,证书是防止中间人攻击的关键。但是证书无非也是数据,是数据就可以被修改或伪造。那么CA证书是如何保证不被修改和伪造的呢?
首先,我们要了解证书的内容。

上图是天猫官网的证书内容,从中可知,一个证书主要包含以下内容:
证书的版本信息;
证书的序列号,每个证书都有一个唯一的证书序列号;
证书所使用的签名算法(即Hash算法);
证书的发行机构名称,命名规则一般采用X.500格式;
证书的有效期,通用的证书一般采用UTC时间格式,它的计时范围为1950-2049;
证书所有人的名称,命名规则一般采用X.500格式;
证书所有人的公钥;
证书发行者对证书的签名。
有同学可能会感觉,内容挺多,也不知道都有啥用。别急。知道了证书的内容,我们还得了解下证书是如何签发的。
证书签发

证书签发有两个关键步骤:
Hash算法做数字签名
数字签名被加密
数字签名的作用是防止数据被修改。只要证书中的数据被修改哪怕一个字符,数字签名就会有极大变化。同时,这个签名是不会相同的,不会被东拼西凑的数据产生同样的签名。
数字签名被加密的目的是防止数字签名被修改或者替换。由于数字签名是用签发方的私钥加密的,浏览器会默认使用证书中携带的公钥进行解密。如果数字签名被替换或者修改,解密出的数字签名就跟原来不一样了。
了解了证书内容和证书签发,就可以讲证书认证了。
证书认证

这里也有两个关键步骤:
数据使用同样的Hash算法计算数字签名
使用公钥解密获得之前的数字签名
如果两个签名相同,好,证书可信。否则不可信。
那么问题来了,证书签发方的公钥从哪获得呢?
仔细看tmall的证书,可发现,*.tmall.com的证书上面还有两层证书。这个叫做证书链(Certificate Chain)。

为啥需要证书链呢?因为某一层证书的公钥需要根据其上一层证书获得。最上层是根证书。
根证书是CA机构才能签发的,特点是自可信。即,无需其他认证,无条件可信。
为啥根证书可信呢?
首先根证书不可信的话,还能信啥
其次,能颁发根证书的机构基本上都有数字证书行业一定年限的行业基础,少则10多年,多则几十年。同时要保证巨额的故障赔付。
正式因为门槛很高,能成为CA的都是极少数的。
其实,证书链只需要两层就可以了,为啥中间还有一层呢?
为了安全
为了方便
先说方便。试想,CA机构也就那么几家,还几乎都在国外。国内任何一个网站需要签发证书的话,都需要跟这几家机构打交道。考虑到网络慢,还有“墙”等因素,这个成本不可小觑。这时就希望如果国内也有证书颁发机构多好。国内的证书颁发机构再由顶级CA机构来认证。就像C由B认证,B由A认证,只要A可信,B就可信,那么C也就可信了。
另一个就是安全,这也是最重要的,因为根证书实在太重要了。godaddy官方给了一个答案是,为了确保root certificates的绝对安全性,将根证书隔离地越严格越好。链接
由于以上原因(当然不止这点儿原因,比如还有利益因素等),就多出了中间一层,这层叫做intermediates Certificates。
也就是说证书分为两种,即root Certificates和intermediates Certificates。
CA的组织结构是一个树结构,一个root CAs下面包含多个intermediates CAs,而intermediates又可以包含多个intermediates CAs。root CAs 和 intermediates CAs都可以颁发证书给用户,但是一般都只是 intermediates CAs跟用户直接打交道。

综上,证书链是一个树形结构,证书的认证是循着链自下而上的逐步认证过程。

还是结合tmall那个例子来zai讲一下证书认证。当访问天猫时,浏览器会收到tmall的证书。为了认证tmall的证书,首先要认证tmall的签发证书globalSign Organization Validation CA,为了认证globalSign Organization Validation CA这个证书,需要认证其签发证书GlobalSign Root CA。这是一个根证书。操作系统和浏览器会默认存储常用根证书。只要是在可信列表中的,这个根证书就是可信的。
引申
MAC系统中可以在“钥匙串访问”中查看存储的根证书。


访问12306时会出现下面的页面

这是由于12306使用的根证书不在默认列表中,需要手动添加即可。

啥是双向认证
单向认证是只有客户端认证服务器的证书
双向认证,就是客户端认证服务器,服务器也需要认证客户端。
大多数情况下,单向认证就够了。像我们常访问的网站,网站没必要验证用户。但是在企业级对接中,双向认证就是必须的了。
网友评论