http https

什么是协议?

网络协议是计算机之间为了实现网络通信而达成的一种“约定”或者”规则“,有了这种”约定“,不同厂商的生产设备,以及不同操作系统组成的计算机之间,就可以实现通信。

什么是http

http(超文本传输协议),运行在TCP/IP协议(网络层协议)之上,是应用层协议,主要解决如何包装数据

发展历史

从上个世界90年代发布以来,http的版本主要有0.9、1.0、1.1、2.0、3.0

具体有什么区别,可以参考我另一篇博客

http报文

上面已经说到http最主要的目的就是包装数据,他是通过http报文来把数据进行包装然后传递,http报文由首部报文主体两个部分组成,首部和报文主体通过一行,报文结构如下,根据首部中的开始行不同分有请求报文响应报文

首部
(空行)
报文主体

请求报文/响应报文

请求报文由三大部分组成,请求行消息报头请求正文

响应报文也由三大部分组成,状态行消息报头响应正文

常见状态码

  • 2XX(成功)
    • 200 成功获取服务器数据
    • 204 no content,请求成功,没有数据返回
  • 3XX(重定向)
    • 301 永久重定向
    • 302 临时重定向
    • 304 未修改
  • 4XX(客户端错误)
    • 400 bad request,请求报文中存在语法错误(可能是传输的字段写错或者没按照格式传输)
    • 403 forbidden,该请求被禁止
    • 404 资源未找到(一般可能是接口地址写错)
    • 405 method not allow,请求方式错误(比如需要post请求,但是用了get请求)
  • 5XX(服务器错误)
    • 500 internal Server error ,表示服务器端在执行请求时发生了错误
    • 502 bad gateway,无效响应
    • 503 service unavailable ,服务器超时,服务器超负载或正在进行停机维护

http + s(security)= https

为什么需要https

HTTP虽然使用极为广泛, 但是却存在不小的安全缺陷, 主要是其数据的明文传送和消息完整性检测的缺乏, 而这两点恰好是网络支付,网络交易等新兴应用中安全方面最需要关注的,https是建立在http之上,在HTTP 的基础下加入TLS/SSL,通过传输加密和身份认证,来保证数据的安全性。

https = http + TLS/SSL(加密) + 身份认证 + 完整性保护

https连接过程

img

加密

为什么需要加密?在http中我们都是通过明文来传输数据的,如果使用http,某一天我在淘宝买东西,使用了我最多钱的银行卡进行付账,那么我就需要明文传输我的银行卡账户和银行卡密码,如果被一些别有用心的人劫持了我这次的请求,那么我的银行卡账号和密码就被别人知道了,我的钱包就岌岌可危了

所以为弥补http明文传输的缺陷,https使用了加密功能,那么加密也有对称加密非对称加密

对称加密

对称加密可以简单理解为,我现在有一把钥匙🔑,我发送信息之前通过这把钥匙进行加密,如果有人给我发送加密信息,我也可以用这把钥匙来进行解密

好处
我们只需一把钥匙🔑就可以完成加密和解密操作,非常简单

坏处
但是同时也暴露了一个问题?如何让别人拿到这把钥匙?难道我们通过明文传输这把钥匙🔑吗?显然是不可以的,这时候就引申出了非对称加密

非对称加密

非对称加密就是为了解决别人如何拿到钥匙🔑,在对称加密中我们只有一把钥匙🔑,那么在非对称加密中我们有两把钥匙:一把是公钥,一把是私钥,公钥加密的内容可以用私钥解密,私钥加密的内容可以用公钥来解密

过程:

  • 浏览器生成公钥A,私钥A’;服务器生成公钥B,私钥B’
  • 通过明文传输浏览器的公钥A给服务器,服务器的公钥B给浏览器
  • 浏览器给服务器发消息时用私钥A’进行加密,服务器通过浏览器的公钥A进行解密,成功拿到浏览器加密数据
  • 服务器给浏览器发消息时用私钥B’进行加密,浏览器通过服务器的公钥B进行解密,成功拿到服务器加密数据

看上去非对称加密成功解决了我们的问题,但是其实还是有问题存在的,那就是中间人攻击,这个我们等一下再说

抛开攻击先不说,https并没有采用非对称加密来进行数据加密,因为加密是一个非常复杂的过程,那么就意味着解密需要大量的耗时,如果我每一条数据加密解密的时间都很长,用户的等到时间也就增长,那么用户体验就会下降,这是我们不愿意看到的

对称加密+非对称加密

那么最终https的加密采用的是对称加密+非对称加密的形式,那么具体是怎样来实现的
过程:

  • 服务器利用非对称加密生成公钥A,私钥A’
  • 浏览器请求时,明文传输公钥A
  • 浏览器拿到公钥A后,利用对称加密生成秘钥X
  • 浏览器用公钥A加密刚刚生成的秘钥X,传回给服务器
  • 服务器用私钥A’解密,拿到秘钥X
  • 所有数据通过秘钥X进行加密解密

这样就解决了对称加密对方无法拿到秘钥的问题,和非对称加密耗时的问题

中间人攻击

就算使用了对称加密➕非对称加密的形式来加密数据,就一定能保证我们的数据不会被泄露吗?显然世界上没有绝对的事情

中间人攻击其实就是在浏览器和服务器之间有个第三者(小三),我们的数据都经过他,他可以加密和解密我们的数据,那么具体过程如下:

  • 浏览器非对称加密生成公钥A,私钥A’
  • 想通过明文发送公钥A给服务器,但是此时这个请求被中间人劫持了
  • 中间人自己也利用非对此加密生成公钥B,私钥B’,并将公钥B发送给服务器
  • 服务器拿到中间人的公钥B后,利用对称加密生成秘钥X,利用公钥B加密后发送回给中间人
  • 中间人利用私钥B’解密,成功拿到秘钥X,偷偷保存起来
  • 中间人再利用劫持到的公钥A,加密秘钥X,发送给回浏览器
  • 浏览器用自己的私钥A’,解密拿到秘钥X,双方开始利用秘钥X进行加密解密数据
  • 中间人成功拿到加密数据

在双方都不知道的情况下,数据就这样被泄露了,因为公钥本身是明文传输的,难道还得对公钥的传输进行加密?为了解决这个问题,我们引出身份认证

身份认证

来一个生活场景,我买了一张飞往北京的机票,如果在没有身份认证的情况下,假如有人知道我买了一张机票并且提前前往机场领取机票,那么我就损失了上千元,所以我们就需要验证身份,证明你本人是你本人,那么我们拿机票时就需要身份证才可以成功拿到机票,由权威的政府机关颁发

那么https也是通过专门的权威机构CA(Certificate Authority)来颁发证书来确定你身份的真实性

那么我们就可以这样理解,在https请求中,CA作为一个大家都信赖的大哥,如果某个网站能够拿到这个大哥颁发的证书,那么这个网站的请求都是可靠的

数字证书

在我们使用https请求之前,可以去向CA机构申请证书,证书内容包括域名、申请者信息、公钥信息等等。如果拥有CA机构颁发的证书,那个请求就是可靠的,那么他是通过什么方式来证明这个证书是可靠的呢?

在申请证书时会有相关信息的填写,被认可后,会根据这些信息生成一个签名,比较证书内容和签名是否一致,就可以知道我们的信息是否有被修改

这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名

数字签名

那么数字签名的生成和验证是一个怎么样的过程

生成:

  • 受信任的CA机构有非对称加密的公钥A,私钥A’
  • 对证书内的相关数据内容进行hash,得到数据X
  • 将数据X用私钥A’进行加密,得到数字签名S

证书内容和数字签名一起组成了证书,发送给浏览器,那么浏览器数如何验证的?

验证:

  • 浏览器拿到证书后,得到证书内容和数字签名S
  • 由于是浏览器信任的机构,所以浏览器保有它的公钥A
  • 用公钥A进行解密签名S,得到在生成过程中,hash过后的证书内容数据X
  • 用证书里指明的hash算法对证书内容进行hash得到数据X’
  • 如果没有被篡改那么 X = X’,等于则表明证书可信

中间人可以对证书内容进行篡改吗?

我们说过中间人攻击,那么中间人可以对证书的内容进行篡改吗?显然是不可以的,假设中间人篡改了证书的原文,但是他没有CA机构的私钥,所以无法修改数字签名。浏览器拿到证书后,会对证书进行验证,解密后就会发现内容不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人

中间人可以直接掉包证书吗?

那么中间人无法修改证书内容,那么中间人直接把整个证书换掉能不能呢?也是不可以的,首先中间人可以通过CA机构获得CA颁发的证书,如果直接把中间人直接把整个证书进行掉包,发送给浏览器。因为证书内部有域名等相关信息,浏览器一对比就会发现,这个证书不是自己的了

总结

既然https可以保证数据的安全,为什么我们不全部都使用https来发送请求呢?首先是http请求已经可以满足我们的大部分需求了;其次证书是需要花钱去购买的,价格也比较高,属于如果是普通的请求我们就不需要https,直接使用http请求就可以