https即 HTTP Secure,HTTP的通信接口部分用SSL和TLS协议代替,并非是一种新的协议。
TLS协议是在SSL3.0的基础上开发的协议,以下统一用TLS协议来说明
http的问题
- 通信使用明文,内容被窃听后存在安全问题
- 不验证通信方的身份,可能遭到伪装
- 无法验证报文的完整性,内容可能遭到篡改
http问题解决思路
明文不行,考虑先加密再传输呢?比如我传输过程中使用一种加密算法,在浏览器端自己加密和解密,服务端也提供对应的策略来加密和解密。前端代码基本属于完全暴露在所有人的面前,这种自己实现加密和解密的机制都会被别人知晓(秘钥都会被看到),毫无安全性可言,另外如果每个人都要这么搞一套,那就是重复造轮子,时间成本巨大,而且还不一定能做到很安全。
当然还包括性能、兼容性等等问题。
通信加密秘钥的安全性问题
秘钥肯定不能硬编码写到代码中,一种解决方式是在每次通信的过程中先生成秘钥,然后的信息再用这个秘钥进行 加密通信 ,但是初次传输过程中,仍然会出现明文传输秘钥的问题,一旦被窃听,后续所有的加密都都白费
初次秘钥传输的问题
密码学中的 非对称加密 可以解决这种场景,非对称加密拥有两个秘钥:公钥和私钥。公钥可以解开私钥加密的内容,私钥可以解开公钥加密的内容,那么只要私钥不泄密,通过公钥加密的内容就算被截取,现有的技术手段,是很难通过截取的内容和公钥得到原有的内容
公钥能否信任
如果获取的公钥是窃听人的公钥,而不是真正服务提供方的公钥,那么后续的通信加密都是使用的窃听人的公钥,窃听人也自然使用自己的私钥可以进行解密。因此获取的公钥必须是能够信任的。
解决方式是把公钥放到数字
证书
中,这个证书由受信任的第三方机构进行颁发,并通过三方的私钥进行加密。客户端发起请求首先会向服务端请求三方的证书,客户端通过三方的公钥进行解密后,就安全拿到了服务端的公钥。
第三方的公钥本身则是由浏览器和操作系统自己去维护
证书被替换的风险
窃听人也可以自己去申请个证书,放上自己的公钥,这样客户端同样也可以通过三方的公钥解密,但是解密出来的却是窃听人的公钥。 解决方式是使用数字签名,证书上涵盖如何根据证书来生成数字签名的方法,与通过第三方机构的公钥解析到数字签名想比较,验证 数字签名 是否一样,一样则表明证书确是要访问的服务的。
比如证书上会写所代表的网站,校验的时候加上访问的网站,就可以得到对应的信息
https的通信过程
https是建立在TLS协议之上的,它的通信过程也是以TLS为基础。首先进行"握手",通过之后再进行通信
TLS握手协议概述
-
客户端发送 ClientHello 信息,包含
- 一个随机数
- 客户端所支持的协议版本
- 客户端支持的对称加密算法
- key_share(表明使用Diffie-Hellman) 或者是 pre_shared_key 或者这两者都有
-
服务端收到 ClientHello 之后,返回一个 ServerHello 信息,包含:
- 协议的版本,比如TLS1.3
- 一个随机数
- 使用的加密算法
- 如果决定使用 (EC)DHE key,那么会包含 "key_share" ;如果使用 PSK key,就会包含 "pre_shared_key"
-
服务端发送证书
如果客户端也需要验证,会再发送一个要证书的请求给客户端
-
服务端发送 Server Hello Done 给客户端,表示Server Hello结束
如果客户端收到了证书请求,会先发送客户端证书
-
客户端对服务器的证书进行校验,没通过则发送警告给使用者,确认是否继续,通过则返回 Pre master secret(这也是客户端产生的一个随机数),这个 Pre master secret 本身会使用证书中的公钥进行加密
-
客户端发送 Change Cipher Spec 报文,表示后续通信都会采用双方商定的加密方法和秘钥发送。
-
客户端会根据之前传递的随机数(2个)以及 Pre master secret 这三个随机数生成一个master_ key,然后从master_key中提取会话用的秘钥,用它加密一段内容,涵盖在这里客户端发送Finished报文中,表示客户端握手阶段结束同时也用来校验加密通道