Android网络中篇:Http与Https详解

一、基础知识

1、TCP/IP协议族

  • IP协议:网络层协议,保证了计算机之间可以发送和接收数据。
  • TCP协议:传输层协议,一种端到端的协议,建立一个虚拟链路用于发送和接收数据,基于重发机制,提供可靠的通信连接。为了方便通信,将报文分割成多个报文段发送。
  • UDP协议:传输层协议,一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

2、TCP3次握手,4次挥手过程

2.1、建立连接协议(三次握手)

(1)客户端发送一个带SYN标志的TCP报文到服务器。(听得到吗?)
(2)服务端回应客户端的报文同时带ACK(acknowledgement,确认)标志和SYN(synchronize)标志。它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。(听得到,你能听到我吗?)
(3)客户必须再次回应服务端一个ACK报文。(听到了,我们可以说话了)

为什么需要“三次握手”?
在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。 主要目的防止server端一直等待,浪费资源。

Android网络中篇:Http与Https详解_第1张图片
2.2、连接终止协议(四次挥手)

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
(4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

Android网络中篇:Http与Https详解_第2张图片

为什么需要“四次挥手”?
那可能有人会有疑问,在tcp连接握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。

3、请求报文

Android网络中篇:Http与Https详解_第3张图片
3.1、请求行

由3部分组成,分别为:请求方法、URL以及协议版本,之间由空格分隔

请求方法:GET、HEAD、PUT、POST等方法,但并不是所有的服务器都实现了所有的方法,部分方法即便支持,处于安全性的考虑也是不可用的
协议版本:常用HTTP/1.1

3.2、请求头部

请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔

  • Host 接受请求的服务器地址,可以是IP:端口号,也可以是域名
  • User-Agent 发送请求的应用程序名称
  • Connection 指定与连接相关的属性,如Connection:Keep-Alive
  • Accept-Charset 通知服务端可以发送的编码格式
  • Accept-Encoding 通知服务端可以发送的数据压缩格式
  • Accept-Language 通知服务端可以发送的语言
  • Range 正文的字节请求范围,为断点续传和并行下载提供可能,返回状态码是206

请求头部的最后会有一个空行,表示请求头部结束,接下来为请求正文,这一行非常重要,必不可少

3.3、请求正文

可选部分,比如GET请求就没有请求正文

4、响应报文

Android网络中篇:Http与Https详解_第4张图片

由3部分组成,分别为:协议版本,状态码,状态码描述,之间由空格分隔

状态码:为3位数字,2XX表示成功,3XX表示资源重定向,4XX表示客户端请求出错,5XX表示服务端出错
206状态码表示的是:客户端通过发送范围请求头Range抓取到了资源的部分数据,得服务端提供支持

4.1、响应头部
  • Server 服务器应用程序软件的名称和版本
  • Content-Type 响应正文的类型(是图片还是二进制字符串)
  • Content-Length 响应正文长度
  • Content-Charset 响应正文使用的编码
  • Content-Encoding 响应正文使用的数据压缩格式
  • Content-Language 响应正文使用的语言
  • Content-Range 正文的字节位置范围
  • Accept-Ranges bytes:表明服务器支持Range请求,单位是字节;none:不支持

正文的内容可以用gzip等进行压缩,以提升传输速率

5、http协议中的多部分对象

报文的主体内可以包含多部分对象,通常用来发送图片、文件或表单等。

5.1、multipart/form-data
Connection: keep-alive
Content-Length: 123
X-Requested-With: ShockwaveFlash/16.0.0.296
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36
Content-Type: multipart/form-data; boundary=Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Range: bytes=0-1024
Cookie: bdshare_firstime=1409052493497

--Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1
Content-Disposition: form-data; name="position"

1425264476444
--Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain

...(file1.txt的数据)...
ue_con_1425264252856
--Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1
Content-Disposition: form-data; name="cm"

100672
--Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1--

a)在请求头中Content-Type: multipart/form-data; boundary=Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1是必须的,boundary字符串可以随意指定
b)上面有3个部分,分别用--boundary进行分隔。Content-Disposition: form-data; name="参数的名称" + "\r\n" + "\r\n" + 参数值
c)--boundary-- 作为结束

二、Https

1、Http的缺点

  • 通信使用明文,内容可能会被窃听 —— 加密通信线路
  • 不验证通信方,可能遭遇伪装 —— 证书
  • 无法验证报文的完整性,可能已被篡改 —— 数字签名

Http+加密+认证+完整性保护=Https

Https就是身披SSL(Secure Socket Layer,安全套接层)协议这层外壳的Http。当使用了SSL之后,Http先和SSL通信,SSL再和TCP通信。

SSL(secure sockets layer):安全套接层,它是在上世纪90年代中期,由网景公司设计的,为解决 HTTP 协议传输内容会被偷窥(嗅探)和篡改等安全问题而设计的,到了1999年,SSL成为互联网上的标准,名称改为TLS(transport layer security):安全传输层协议,两者可视为同一种东西的不同阶段。

Android网络中篇:Http与Https详解_第5张图片

2、Https的工作原理

HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。握手过程的具体描述如下:

  • 浏览器将自己支持的一套加密规则发送给网站。
  • 网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
  • 浏览器获得网站证书之后浏览器要做以下工作:
    a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
    b) 如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
    c) 使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
  • 网站接收浏览器发来的数据之后要做以下的操作:
    a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
    b) 使用密码加密一段握手消息,发送给浏览器。
  • 浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。另外,HTTPS一般使用的加密与HASH算法如下:

  • 非对称加密算法:RSA,DSA/DSS
  • 对称加密算法:AES,RC4,3DES
  • HASH算法:MD5,SHA1,SHA256

HTTPS对应的通信时序图如下:

Android网络中篇:Http与Https详解_第6张图片

3、证书分类

SSL 证书大致分三类:

  • 认可的证书颁发机构(如: VeriSign), 或这些机构的下属机构颁发的证书.
  • 没有得到认可的证书颁发机构颁发的证书.
  • 自签名证书, 自己通过JDK自带工具keytool去生成一个证书,分为临时性的(在开发阶段使用)或在发布的产品中永久性使用的两种.

只有第一种, 也就是那些被安卓系统认可的机构颁发的证书, 在使用过程中不会出现安全提示。对于向权威机构(简称CA,Certificate Authority)申请过证书的网络地址,用OkHttp或者HttpsURLConnection都可以直接访问 ,不需要做额外的事情 。但是申请需要$$ (每年要交 100 到 500 美元不等的费用)。

CA机构颁发的证书有3种类型:
域名型SSL证书(DV SSL):信任等级普通,只需验证网站的真实性便可颁发证书保护网站;
企业型SSL证书(OV SSL):信任等级强,须要验证企业的身份,审核严格,安全性更高;
增强型SSL证书(EV SSL):信任等级最高,一般用于银行证券等金融机构,审核严格,安全性最高,同时可以激活绿色网址栏。

4、HTTPS协议和HTTP协议的区别:

  • https协议需要到ca申请证书,一般免费证书很少,需要交费。
  • http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
  • http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
  • http的连接很简单,是无状态的 。
  • HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议, 要比http协议安全。

参考文献

HTTPS工作原理和TCP握手机制
Https单向认证和双向认证

你可能感兴趣的:(Android网络中篇:Http与Https详解)