使用 HTTP 传输的内容很容易被中间人窃取、伪造和篡改,通常我们把这种攻击方式称为中间人攻击。
安全层(SSL/TLS)有两个主要的职责:对发起 HTTP 请求的数据进行加密操作和对接收到 HTTP 的内容进行解密操作。
第一版:使用对称加密提到加密,最简单的方式是使用对称加密。所谓对称加密是指加密和解密都使用的是相同的密钥。
第二版:使用非对称加密,和对称加密只有一个密钥不同,非对称加密算法有 A、B 两把密钥,如果你用 A 密钥来加密,那么只能使用 B 密钥来解密;反过来,如果你要 B 密钥来加密,那么只能用 A 密钥来解密。
在 HTTPS 中,服务器会将其中的一个密钥通过明文的形式发送给浏览器,我们把这个密钥称为公钥,服务器自己留下的那个密钥称为私钥。顾名思义,公钥是每个人都能获取到的,而私钥只有服务器才能知道,不对任何人公开。
首先浏览器还是发送加密套件列表给服务器。
然后服务器会选择一个加密套件,不过和对称加密不同的是,使用非对称加密时服务器上需要有用于浏览器加密的公钥和服务器解密 HTTP 数据的私钥,由于公钥是给浏览器加密使用的,因此服务器会将加密套件和公钥一道发送给浏览器。
最后就是浏览器和服务器返回确认消息。
这样浏览器端就有了服务器的公钥,在浏览器端向服务器端发送数据时,就可以使用该公钥来加密数据。由于公钥加密的数据只有私钥才能解密,所以即便黑客截获了数据和公钥,他也是无法使用公钥来解密数据的。
因此采用非对称加密,就能保证浏览器发送给服务器的数据是安全的了,这看上去似乎很完美,不过这种方式依然存在两个严重的问题。
第一个是非对称加密的效率太低。这会严重影响到加解密数据的速度,进而影响到用户打开页面的速度。
第二个是无法保证服务器发送给浏览器的数据安全。虽然浏览器端可以使用公钥来加密,但是服务器端只能采用私钥来加密,私钥加密只有公钥能解密,但黑客也是可以获取得到公钥的,这样就不能保证服务器端数据的安全了。
第三版:对称加密和非对称加密搭配使用
基于以上两点原因,我们最终选择了一个更加完美的方案,那就是在传输数据阶段依然使用对称加密,但是对称加密的密钥我们采用非对称加密来传输。
从图中可以看出,改造后的流程是这样的:
首先浏览器向服务器发送对称加密套件列表、非对称加密套件列表和随机数 client- random;
服务器保存随机数 client-random,选择对称加密和非对称加密的套件,然后生成随机数 service-random,向浏览器发送选择的加密套件、service-random 和公钥;
浏览器保存公钥,并利用 client-random 和 service-random 计算出来 pre-master, 然后利用公钥对 pre-master 加密,并向服务器发送加密后的数据;
最后服务器拿出自己的私钥,解密出 pre-master 数据,并返回确认消息。
到此为止,服务器和浏览器就有了共同的 client-random、service-random 和 pre-master,然后服务器和浏览器会使用这三组随机数生成对称密钥,因为服务器和浏览器使用同一套方法来生成密钥,所以最终生成的密钥也是相同的。
有了对称加密的密钥之后,双方就可以使用对称加密的方式来传输数据了。需要特别注意的一点,pre-master 是经过公钥加密之后传输的,所以黑客无法获取到pre-master,这样黑客就无法生成密钥,也就保证了黑客无法破解传输过程中的数据了。
第四版:添加数字证书 比如说生活中怎么证明房子是你的,通过房管局这个权威机构来给你办理房产证,有房产证就可以证明。同样在怎么证明这个服务器是某个网站,就需要有权威机构颁发的证书CA,数字证书(Digital Certificate)。
- 服务器没有直接返回公钥给浏览器,而是返回了数字证书,而公钥正是包含在数字证书中的;
- 在浏览器端多了一个证书验证的操作,验证了证书之后,才继续后续流程。
通过引入数字证书,我们就实现了服务器的身份认证功能,这样即便黑客伪造了服务器,但是由于证书是没有办法伪造的,所以黑客依然无法欺骗用户。
如何申请数字证书
申请域名公司需要准备一套私钥和公钥,私钥留着自己使用;
然后公司向 CA 机构提交公钥、公司、站点等信息并等待认证,这个认证过程可能是收费的;
CA 通过线上、线下等多种渠道来验证极客时间所提供信息的真实性,如公司是否存在、企业是否合法、域名是否归属该企业等;
如信息审核通过,CA 会向公司签发认证的数字证书,包含了极客时间的公钥、组织信息、CA 的信息、有效时间、证书序列号等,这些信息都是明文的,同时包含一个 CA 生成的签名。
数字签名的过程还需要解释下:首先 CA 使用Hash 函数来计算公司提交的明文信息,并得出信息摘要;然后 CA 再使用它的私钥对信息摘要进行加密,加密后的密文就是 CA 颁给公司的数字签名。这就相当于房管局在房产证上盖的章,这个章是可以去验证的,同样我们也可以通过数字签名来验证是否是该 CA 颁发的。
申请和使用证书的过程中,还需要注意以下三点:
-
申请数字证书是不需要提供私钥的,要确保私钥永远只能由服务器掌握;
-
数字证书最核心的是 CA 使用它的私钥生成的数字签名;
-
内置 CA 对应的证书称为根证书,根证书是最权威的机构,它们自己为自己签名,我们把这称为自签名证书。
总结:
由于 HTTP 的明文传输特性,在传输过程中的每一个环节,数据都有可能被窃取或者篡改,这倒逼着我们需要引入加密机制。于是我们在 HTTP 协议栈的 TCP 和 HTTP 层之间插入了一个安全层,负责数据的加密和解密操作。
我们使用对称加密实现了安全层,但是由于对称加密的密钥需要明文传输,所以我们又将对称加密改造成了非对称加密。但是非对称加密效率低且不能加密服务器到浏览器端的数据,于是我们又继续改在安全层,采用对称加密的方式加密传输数据和非对称加密的方式来传输密钥,这样我们就解决传输效率和两端数据安全传输的问题。
采用这种方式虽然能保证数据的安全传输,但是依然没办法证明服务器是可靠的,于是又引入了数字证书,数字证书是由 CA 签名过的,所以浏览器能够验证该证书的可靠性。