https你很熟?灵魂三连问之https安全在哪里?客户端如何验证https证书的合法性?ssl是如何加密数据的?

2023-08-17 16:27:46 188 林溪

http

学过网络模型的都知道,HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,http是基于tcp协议传输数据的,而tcp是一种数据流传输协议。那么我们发送的数据,就会以明文的方式传输

http存在的问题

接下来我们用wireshark抓一个明文包看看,我这边随便找了某个公司的后台,是使用ip登录的,我们设置一下wireshark

  • 因为我是使用无线wifi上网的,所以我监听第一个网络接口
  • 添加过滤器,过滤其他的网络数据http and ip.dst == 115.28 ip填写的是对方的ip地址
  • 接下来我们发送一个登录请求,并抓包看一下,我们登录的用户名密码都是明文传输的,当然,用户名密码我是瞎写的,我也不知道别人的用户名密码
  • 那么从上面我们看到,http请求很容易就被第三方窃听,篡改,甚至是冒充,哪怕是http2.0使用了二进制传输,还是可以被解码。那么怎么办?我们对http的请求需要安全,需要保证http的secure,所以,https就被提出来了。

https

由于http的明文传输不安全,易篡改,易伪装,所以在1994年网景公司提出了https,即超文本传输安全协定(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种透过计算机网路进行安全通讯的传输协议。

  • 接下来我再来请求一个https的登录,也是随便找一个登录后台,我们只抓到了TLSv1.2(基于tls的升级)和一个tcp,并看不到里面的请求数据,具体的请求路径也抓取不到

tls和ssl

SSL(Secure Sockets Layer)译为「安全套接字协议」,是网景公司1994年提出的。TLS(Transport Layer Security)译为「传输层安全性协议」,是互联网标准化组织ISOC接替网景公司后,在1999年发布的,是ssl的升级版。 ssl/tls协议处于传输层和应用层之间,就是要完成在传输之前对数据的加密 那么ssl/tls是怎么解决上面我们说的,被窃听,被篡改,被伪造的问题的呢?

窃听

  • 对称加密 防止窃听对简单的方式就是对信息混淆处理,比如加密,但是加密之后客户端和服务端都得能解出来才行,所以需要一个对称加密的算法,但是对称加密后,别人知道算法了也可以破解,怎么办呢?那么我们双方约定一个秘钥,使用秘钥对数据加密后传输,对方再使用秘钥解密就可以了。 但是问题又来了,服务端存储秘钥可以,但是我们控制不了客户端,既然是秘钥,存客户端肯定就能被看到,被人破解。那怎么办?
  • 非对称加密 既然我们不能将秘钥存储在客户端,那么我们可以这样吧,我们加密数据用一个公钥,但是用另一个私钥去解密,那么服务端将公钥给客户端,客户端拿到公钥对数据加密后穿给服务端,这样的话就算被截获了,没有私钥也解不了。这样的话就解决了客户端给服务端发送数据安全传输的问题。这就是单向非对称加密 但是服务端如果想安全传输给客户端怎么办呢?比如银行系统,为了验证客户端的安全,网银刚出来的时候,会给我们一个网盾,插电脑上才可以进行网上银行的相关操作。其实这个网盾的功能,就是一个秘钥。客户端根据有了公钥和秘钥,就可以解密数据了。

篡改

通过非对称加密,我们防止了数据窃听,但是在传输过程中,如果数据被对方篡改了,我们怎么去校验呢?那就需要我们给数据加签,还是咱们说的网银用的网盾,网盾里面有一套秘钥对,和银行的服务端是配套的,用户发送数据前,先会根据请求体生成签名,然后再对数据进行加密传输,这样的话,服务端收到数据后就会做两个验证,一个是对数据解密,解密后对签名就行比对。这样就杜绝了传输过程中对数据的篡改。

中间人伪造

前面我们说过,在传输之前,我们需要用公钥对数据加密,但是公钥是明文传输的,那么可能就会出现如下图的情况,中间人对客户端伪装成服务端,对服务端又伪装成客户端,客户端和服务端都以为已经拿到了对方的公钥,对数据加密传输了,而其实用的却是中间人的公钥,那中间人自然可以加密解密,窃取,篡改了。 那怎么办呢?

证书认证中心

既然可能出现中间人在中间截获,那么我们能不能验证一下我们的公钥是真实的?这时候,ca认证就出来了,服务端和客户端不在直接发送公钥,而是把公钥先发送到ca,ca根据公钥生成一份证书,服务端将证书发送给客户端,ca怎么生成的证书呢?我们以nginx的配置为例来看一下

nginx配置https

我们先来看一张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四次握手的过程又是什么样子的呢:

  • 客户端向服务端索要证书
  • 服务端发送证书
  • 客户端验证证书,提取公钥,发送对称加密的密钥。
  • 服务端收到密钥,响应OK
在这里插入图片描述

https的缺点

我们前面看过了https是如何加密传输的,保证了数据的安全,但同时,由于在加密过程中使用了对称加密和非对称加密以及解密,都会带来一定的耗时。但是随着http2.0的多路复用的实现,这种影响越来越小了。