查漏补缺之HTTP及HTTPS

787 阅读14分钟

HTTP定义

超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。

HTTP报文格式

HTTPS定义

《图解HTTP》这本书中曾提过HTTPS是身披SSL外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。

PS:TLS是传输层加密协议,前身是SSL协议,由网景公司1995年发布,有时候两者不区分。 简单来说,HTTPS就是HTTP+SSL,增强了安全性。

HTTP 与 HTTPS 特点分析

HTTP特点:

  • 无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作

  • 无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。

  • 基于请求和响应:基本的特性,由客户端发起请求,服务端响应

  • 简单快速、灵活

  • 通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性

HTTPS特点:

  • 内容加密:采用混合加密技术,中间者无法直接查看明文内容

  • 验证身份:通过证书认证客户端访问的是自己的服务器

  • 保护数据完整性:防止传输的内容被中间人冒充或者篡改

HTTP通信原理

客户端输入URL回车,DNS解析域名得到服务器的IP地址,服务器在80端口监听客户端请求,端口通过TCP/IP协议(可以通过Socket实现)建立连接。HTTP属于TCP/IP模型中的运用层协议,所以通信的过程其实是对应数据的入栈和出栈。

TCP三次握手及四次挥手

先解释一下各个码的含义

序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。

确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

PS:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。

TCP三次握手

  • 第一次握手:建立连接。客户端发送连接请求同步SYN报文,SYN=1,seq=x。
  • 第二次握手:服务器接收SYN报文,进行确认,设置ACK=1,表示确认。同时设置自己的SYN=1,设置seq=y,ack=x+1。其中seq为服务器生成的序列号,ack为第一次握手的seq序号加一。
  • 第三次握手:客户端接收SYN+ACK报文,设置ACK=1,表示确认收到。同时设置seq=x+1,ack=y+1。其中seq为客户端生成的下一个序列号,ack为第二次握手的seq序号加一。

TCP四次挥手

  • 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  • 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  • 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  • 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  • 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

HTTPS原理

在正式讲解HTTPS协议之前,我们首先要知道一些密码学的知识。

密码学

明文: 明文指的是未被加密过的原始数据。

密文:明文被某种加密算法加密之后,会变成密文,从而确保原始数据的安全。密文也可以被解密,得到原始的明文。

密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥,分别应用在对称加密和非对称加密上。

对称加密:对称加密又叫做私钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。对称加密的特点是算法公开、加密和解密速度快,适合于对大数据量进行加密,常见的对称加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。 其加密过程如下:明文 + 加密算法 + 私钥 => 密文 解密过程如下:密文 + 解密算法 + 私钥 => 明文 对称加密中用到的密钥叫做私钥,私钥表示个人私有的密钥,即该密钥不能被泄露。 其加密过程中的私钥与解密过程中用到的私钥是同一个密钥,这也是称加密之所以称之为“对称”的原因。由于对称加密的算法是公开的,所以一旦私钥被泄露,那么密文就很容易被破解,所以对称加密的缺点是密钥安全管理困难。

非对称加密:非对称加密也叫做公钥加密。非对称加密与对称加密相比,其安全性更好。对称加密的通信双方使用相同的密钥,如果一方的密钥遭泄露,那么整个通信就会被破解。而非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公共的密钥,任何人都可以获得该密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。 被公钥加密过的密文只能被私钥解密,过程如下: 明文 + 加密算法 + 公钥 => 密文, 密文 + 解密算法 + 私钥 => 明文 被私钥加密过的密文只能被公钥解密,过程如下: 明文 + 加密算法 + 私钥 => 密文, 密文 + 解密算法 + 公钥 => 明文 由于加密和解密使用了两个不同的密钥,这就是非对称加密“非对称”的原因。 非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。 在非对称加密中使用的主要算法有:RSA、Elgamal、Rabin、D-H、ECC(椭圆曲线加密算法)等。

HTTPS通信过程

HTTPS协议 = HTTP协议 + SSL/TLS协议,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。

SSL的全称是Secure Sockets Layer,即安全套接层协议,是为网络通信提供安全及数据完整性的一种安全协议。

TLS的全称是Transport Layer Security,即安全传输层协议,,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。虽然TLS与SSL3.0在加密算法上不同,但是在我们理解HTTPS的过程中,我们可以把SSL和TLS看做是同一个协议

HTTPS在传输的过程中会涉及到三个密钥:

  • 服务器端的公钥和私钥,用来进行非对称加密,

  • 客户端生成的随机密钥,用来进行对称加密

一个HTTPS请求实际上包含了两次HTTP传输,可以细分为9步。

1.客户端向服务器发起HTTPS请求,连接到服务器的443端口,发送的信息主要是随机值1和客户端支持的加密算法。

2.服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。

3.服务器生成随机值2和匹配好的协商加密算法(这个加密算法一定是client发送给server加密算法的子集)发送给客户端

4.服务器将自己的公钥发送给客户端。

5.客户端收到服务器端的公钥之后,会对公钥进行检查,验证其合法性,如果发现发现公钥有问题,那么HTTPS传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。

6.客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥(形成新的密文)发送给服务器。

7.服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。

8.然后服务器将加密后的密文发送给客户端。

9.客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。

在通信过程中,怎么保证保证服务器给客户端下发的公钥是真正的公钥,而不是中间人伪造的公钥呢?

答案:数字证书

数字证书

通过观察HTTPS的传输过程,我们知道,当服务器接收到客户端发来的请求时,会向客户端发送服务器自己的公钥,但是黑客有可能中途篡改公钥,将其改成黑客自己的,所以有个问题,客户端怎么信赖这个公钥是自己想要访问的服务器的公钥而不是黑客的呢? 这时候就需要用到数字证书。

在讲数字证书之前,先说一个小例子。假设一个镇里面有两个人A和B,A是个富豪,B想向A借钱,但是A和B不熟,怕B借了钱之后不还。这时候B找到了镇长,镇长给B作担保,告诉A说:“B人品不错,不会欠钱不还的,你就放心借给他吧。” A听了这话后,心里想:“镇长是全镇最德高望重的了,他说B没问题的话那就没事了,我就放心了”。 于是A相信B的为人,把钱借给了B。

与此相似的,要想让客户端信赖公钥,公钥也要找一个担保人,而且这个担保人的身份必须德高望重,否则没有说服力。这个担保人的就是证书认证中心(Certificate Authority),简称CA。 也就是说CA是专门对公钥进行认证,进行担保的,也就是专门给公钥做担保的担保公司。 全球知名的CA也就100多个,这些CA都是全球都认可的,比如VeriSign、GlobalSign等,国内知名的CA有WoSign。

那CA怎么对公钥做担保认证呢?CA本身也有一对公钥和私钥,CA会用CA自己的私钥对要进行认证的公钥进行非对称加密,此处待认证的公钥就相当于是明文,加密完之后,得到的密文再加上证书的过期时间、颁发给、颁发者等信息,就组成了数字证书。

不论什么平台,设备的操作系统中都会内置100多个全球公认的CA,说具体点就是设备中存储了这些知名CA的公钥。当客户端接收到服务器的数字证书的时候,会进行如下验证:

首先客户端会用设备中内置的CA的公钥尝试解密数字证书,如果所有内置的CA的公钥都无法解密该数字证书,说明该数字证书不是由一个全球知名的CA签发的,这样客户端就无法信任该服务器的数字证书。

如果有一个CA的公钥能够成功解密该数字证书,说明该数字证书就是由该CA的私钥签发的,因为被私钥加密的密文只能被与其成对的公钥解密。

除此之外,还需要检查客户端当前访问的服务器的域名是与数字证书中提供的“颁发给”这一项吻合,还要检查数字证书是否过期等。

参考资料

blog.csdn.net/xiaoming100…

www.cnblogs.com/bj-mr-li/p/…

blog.csdn.net/iispring/ar…

www.jianshu.com/p/7158568e4…