学过网络模型的都知道,HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,http是基于tcp协议传输数据的,而tcp是一种数据流传输协议。那么我们发送的数据,就会以明文的方式传输
接下来我们用wireshark抓一个明文包看看,我这边随便找了某个公司的后台,是使用ip登录的,我们设置一下wireshark
http and ip.dst == 115.28
ip填写的是对方的ip地址
由于http的明文传输不安全,易篡改,易伪装,所以在1994年网景公司提出了https,即超文本传输安全协定(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种透过计算机网路进行安全通讯的传输协议。
SSL(Secure Sockets Layer)译为「安全套接字协议」,是网景公司1994年提出的。TLS(Transport Layer Security)译为「传输层安全性协议」,是互联网标准化组织ISOC接替网景公司后,在1999年发布的,是ssl的升级版。 ssl/tls协议处于传输层和应用层之间,就是要完成在传输之前对数据的加密 那么ssl/tls是怎么解决上面我们说的,被窃听,被篡改,被伪造的问题的呢?
通过非对称加密,我们防止了数据窃听,但是在传输过程中,如果数据被对方篡改了,我们怎么去校验呢?那就需要我们给数据加签,还是咱们说的网银用的网盾,网盾里面有一套秘钥对,和银行的服务端是配套的,用户发送数据前,先会根据请求体生成签名,然后再对数据进行加密传输,这样的话,服务端收到数据后就会做两个验证,一个是对数据解密,解密后对签名就行比对。这样就杜绝了传输过程中对数据的篡改。
前面我们说过,在传输之前,我们需要用公钥对数据加密,但是公钥是明文传输的,那么可能就会出现如下图的情况,中间人对客户端伪装成服务端,对服务端又伪装成客户端,客户端和服务端都以为已经拿到了对方的公钥,对数据加密传输了,而其实用的却是中间人的公钥,那中间人自然可以加密解密,窃取,篡改了。 那怎么办呢?
既然可能出现中间人在中间截获,那么我们能不能验证一下我们的公钥是真实的?这时候,ca认证就出来了,服务端和客户端不在直接发送公钥,而是把公钥先发送到ca,ca根据公钥生成一份证书,服务端将证书发送给客户端,ca怎么生成的证书呢?我们以nginx的配置为例来看一下
我们先来看一张nginx配置https的配置文件
其中pem文件存储的是公钥,key文件存储是私钥,这两个文件哪来的呢,一般是由国际权威的CA机构颁发的,比如Symantec、Comodo、GeoTrust等。拿到这两个公钥和私钥后,如果有人向服务端发起请求,证书就会被发送给客户端,那么在客户端就可以看到类似这样一个证书
或者也可以使用以下命令生成证书openssl req -new -x509 -key server.key -out server.crt -days 3650
,这会生成一个3650天的有效期的证书,但是权威机构认不认为你的证书是安全的就是另外一回事了。
如果你用的是ca机构发给你的pem和key,那么ca认为证书就是合法的,如果是你自己生产的证书,那么ca就认为你是不安全的,浏览器就会提示你。那么浏览器是怎么知道证书是否合法呢?其实,在操作系统中,有一份根证书列表,用来对比你的证书是否在证书列表中,在就代表是合法的。比如在Windows中,证书列表存在C:\Windows\System32\certsrv\CertEnrol文件中,看一下macos里面的根证书列表,在浏览器中,也会内置根证书 但是,由于浏览器不可能在每个访问者访问每个网站时都向CA查询一次,而是查询本地存储的根列表,而是定期查询更新CA最新的CRL,所以,有时候证书虽然被吊销了,浏览器依旧会信任的情况,但是这个是时间不会太久。
那么我们来看一下,证书是什么时候传递给客户端的,我们看下面的图,tcp三次握手之后,就会发送ssl/tls四次握手发送证书 那么SSL/TLS四次握手的过程又是什么样子的呢:
我们前面看过了https是如何加密传输的,保证了数据的安全,但同时,由于在加密过程中使用了对称加密和非对称加密以及解密,都会带来一定的耗时。但是随着http2.0的多路复用的实现,这种影响越来越小了。