Android网络编程学习笔记(一)

应用层 HTTP/HTTPS协议

1 定义

HTTP协议(超文本传输协议)用于从www服务器传输超文本到本地浏览器的传送协议,HTTP协议是应用层协议,由请求和响应构成,HTTP默认端号80,HTTPS端口号为443

Android网络编程学习笔记(一)_第1张图片
HTTP位置

2 简单的HTTP协议                      

1、简单快速:客户向服务器请求服务时,只需传送请求方法路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

2、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

3、HTTP 0.9和1.0使用非持续连接:限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接。HTTP 1.1默认使用持续连接:不必为每个web对象创建一个新的连接,一个连接可以传送多个对象,采用这种方式可以节省传输时间,减轻服务器端的负载。

4、无状态:HTTP协议是无状态协议无状态是指协议对于事务处理没有记忆能力。缺少状态意味着无法根据之前的状态进行本次的请求处理,如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

5、支持B/S及C/S模式。

6、管线化: 管线化技术可以做到同时并行发送多个请求,不需要一个接一个的等待响应

2.1 HTTP工作流程                  

一次HTTP操作称为一个事务,其工作过程可分为四步:

1、首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。

2、建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。

3、服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

 4、客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。

如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。

2.2 HTTP之请求消息Request 

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

  请求行请求首部空行请求数据四个部分组成。

1、GET请求/POST请求

Android网络编程学习笔记(一)_第2张图片
请求数据抓包

第一部分:请求行,用来说明请求类型、请求方法、要访问的资源以及所使用的HTTP版本。

GET说明请求类型为GET为要访问的资源,该行的最后一部分说明使用的是HTTP1.1版本。

第二部分:请求首部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息,首部中的行以一个回车换行对结束

从第二行起为请求首部,HOST将指出请求的目的地。User-Agent,服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础。该信息由你的浏览器来定义,并且在每个请求中自动发送等等。

第三部分:空行,请求首部后面的空行是必须的

即使第四部分的请求数据为空,也必须有空行。

第四部分:请求数据也叫主体,可以添加任意的其他数据。

2、请求首部

User-Agent:客户端支持的浏览器类型和版本

Accept:告诉服务器客户端可以处理的数据类型,而以x-开头,表示可以支持自由定义非标准的定制类型和子类型,可使用type/subtype这种形式,一次指定多种媒体类型。可以设置权重值来为请求的资源类型设置优先级,用分号(;)分隔。

Connection: 指定值为Keep-Alive,表示它希望重用一个Socket,URL类默认地支持HTTP Keep-Alive

Authorization: 用来告知服务器,用户代理的认证信息

Cookie: 该客户端的Cookie信息

Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)

Host请求的主机名,允许多个域名同处一个IP地址,即虚拟主机

If-Modified-Since:告知服务器若该字段值早于资源的更新时间,则希望能处理该请求

Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式

最后,请求以一个空行结束,即包括两个回车/换行对,一旦服务器看到这个标识,就会开始通过同一个连接向客户端发送它的响应。

2.3 HTTP之响应消息Response

一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。

HTTP响应也由四个部分组成,分别是:状态行消息报头空行响应正文

Android网络编程学习笔记(一)_第3张图片
响应数据抓包

第一部分:状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。

第二部分:消息报头,用来说明客户端要使用的一些附加信息

第三部分:空行,消息报头后面的空行是必须的

第四部分:响应正文,服务器返回给客户端的文本信息。

2、响应首部

ETag:告知客户端实体标识,它是一种可将资源以字符串形式做唯一性标识的方式,服务器会为每份资源分配对应的ETag值。ETag值有强ETag和弱ETag之分。

Location:用于重定向接受者到一个新的位置,常用在更换域名的时候

Server:告知客户端当前服务器安装的HTTP服务器应用程序的信息,与User-Agent请求报头是相对应的

Retry_After:告知客户端应在多久之后再次发送请求

Set-Cookie:设置客户端的管理状态

WWW-Authenticate:用于HTTP访问认证,告知客户端适用于访问请求URI所指定资源的认证方案。

2.4 实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

Content-Type:发送给接收者的实体正文的媒体类型

Content-Lenght:正文的长度

Date:生成响应的日期和时间;

Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读

Content-Encoding:被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。

Content-MD5:该字段是一串MD5算法生成的值,用于检查报文主体在传输过程中是否保持完整,以及确认传输到达。

Last-Modified:指示资源的最后修改日期和时间

Expires:响应过期的日期和时间

2.5 HTTP之状态码                   

状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

1xx:指示信息--表示请求已接收,正在处理

2xx:成功--表示请求已被成功接收、理解、接受

3xx:重定向--要完成请求必须进行更进一步的操作

4xx:客户端错误--请求有语法错误或请求无法实现

5xx:服务器端错误--服务器未能实现合法的请求

常见状态码:

302 Found 重定向,新的URL会在response 中的Location中返回,浏览器将会自动使用新的URL发出新的Request

204 No Content 代表服务器接收的请求已成功处理,但返回的响应报文中不含实体的主体部分

206 Partial Content 代表客户端进行了范围请求

301 Moved Permanently 代表永久性重定向,请求的资源已被分配了新的URI,以后应使用资源现在所指的URI

302 Found 代表临时性重定向,请求的资源已被分配了新的URI,希望用户能使用新的URI访问。和状态码301相似,但是302是指资源临时被移动,而301是永久

303 See Other 该状态码与302有着相同的功能,但是303状态码明确表示客户端应当采用GET方法获取资源

304 Not Modified 代表上次的文档已经被缓存了, 还可以继续使用

400 Bad Request 客户端请求与语法错误,不能被服务器所理解

401 Unauthorized 请求未经授权,发送的请求需要有通过HTTP认证的认证信息,当浏览器初次接收到401响应时会弹出认证对话窗口

403 Forbidden 服务器收到请求,但是访问被服务器拒绝了

404 Not Found 请求资源不存在(输错了URL)

500 Internal Server Error 服务器发生了不可预期的错误

503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常。

2.6 HTTP请求方法                  

根据HTTP标准,HTTP请求可以使用多种请求方法。

GET  请求指定的资源信息,指定的资源经服务器解析后返回响应内容

POST  传输实体的主体

PUT  用来传输文件,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置,但是HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的WEB网站不使用该方法。

GET和POST的区别

     1、GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.

     2、GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

     3、GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。

     4、GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码。

HEAD  获取报文首部,该方法和GET方法一样,只是不返回报文主体部分,用于确认URI的有效性及资源更新的日期时间等

DELETE  按请求URI删除指定的资源,与PUT方法相反,该方法也不带验证机制

OPTIONS  用来查询针对请求URI指定的资源支持的方法

TRACE  追踪路径,让Web服务器端将之前的请求通信环回给客户端的方法

CONNECT   要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信,将通信内容用SSL和TLS协议加密后经网络隧道传输

2.7 Http缺点

1、Http不具备加密的功能,所以通信使用明文,内容可能会被窃听;

2、Http协议中的请求和响应不会对通信方进行确认,可能会遭遇伪装;

3、Http无法证明报文的完整性,可能已遭篡改。

3 HTTPS

简单地来说,是基于ssl的http协议,依托ssl协议,https协议能够确保整个通信是加密的,密钥随机产生,并且能够通过数字证书验证通信双方的身份,以此来保障信息安全。所以说,HTTP + 加密 + 认证 + 完整性保护 就是HTTPS

3.1 Https协议栈

https协议在http协议和tcp协议之间增加一层安全层(SSL/TLS协议),所有请求和响应的数据在网络传输之前都会先进行加密,然后在进行传输。

Android网络编程学习笔记(一)_第4张图片
HTTPS

SSL的全称是Secure Socket Layer,既安全套接层。SSL协议独立于应用层,应用层的http,ftp,ssh都可以建立在ssl之上。TLS全程是Transport Layer Security,传输层安全协议,是基于SSL的通用化协议,同样位于应用层和传输层之间,正逐步接替SSL成为下一代网络安全协议。

SSL/TLS分为两层:

Record Protocol  记录协议:记录协议建立在可靠的传输协议(TCP)之上,提供数据封装,加密解密,数据压缩,数据校验等基本功能。

Handshake Protocol  握手协议:建立在握手协议之上,在实际的数据传输开始前,进行加密算法的协商,通信密钥的交换,通信双方身份的认证。

针对HTTP协议的缺点,HTTPS提供了一下服务确保安全性:

1、利用通信加密和内容加密的方式,防止数据被窃听;

2、认证用户和服务器,防止通信方被伪装;

3、对数据完整性保护,确保数据不被篡改

3.2 HTTPS安全通信机制

       前面讲到,SSL/TLS协议分为两层,Handshake Protocol和Record Protocol。其中Handshake Protocol用来协商密钥,协议的大部分内容就是通信双方如何利用它来安全的协商出一份密钥。 Record Protocol则定义了传输的格式。

       HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制,在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

Android网络编程学习笔记(一)_第5张图片
HTTPS通信流程

客户端发出请求(ClientHello)

       如果客户端想要请求,则会向服务器发送ClientHello,由于不同客户端对加密算法的支持程度不一样,但是SSL/TLS协议必须使用同一种加密算法进行加密,所以在SSL/TLS握手阶段,客户端需要将自己支持的算法(Cipher Suite)告诉服务端,除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的会话密钥Master Secret 。

服务器响应

       当收到客户端发送的请求后,服务器匹配ClientHello中的信息,从客户端支持的加密算法中筛选出一个可行的加密算法,并将筛选结果通知给客户端;

       同时也会产生一个随机数发送给客户端,需要这两个随机数来产生会话密钥;

       服务器还需要向客户端发送自己的证书,用来服务器的身份认证。证书需要向专门的数字证书认证机构(CA)申请,颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。

       如果服务器发送的证书中没有提供足够的信息时,还会发送Server Key Exchange

       同时,如果是双向验证,则需要验证客户端的身份,服务器会向客户端发送身份验证请求Cerficate Request ,要求客户端发送证书进行合法性验证;

       最后,服务器发送Server Hello Done消息给客户端,ServerHello结束。

客户端响应

       客户端收到验证请求消息后,会向服务器发送自己的证书,让服务器验证自己的身份;

       随后会对服务器的证书进行验证,即利用CA机构的公开密钥验证服务器证书上的数字签名,如果验证有效,取出服务器的公钥,否则警告提示访问者;客户端生成第三个随机数,并用服务器的公钥加密,然后发送给服务器Client Key Exchange,这个加密的随机数称为Pre-master Secret,这样,客户端和服务器都同时有了三个随机数,双方会使用之前协商好的加密算法,各自生成本次会话要使用的同一把“会话密钥”,即对称加密算法,

       接着,客户端发送ChangeCipherSpec,告知服务器,客户端已经切换到之前协商好的加密套件的状态,此后的报文都会采用生成的会话密钥加密;

       自此,客户端的握手过程结束,但会发送一段Encrypted Handshake Message报文,该报文包含连接至今所有报文的Hash校验值,并用会话密钥加密,用来供服务器校验,如果服务器能够正确校验该报文,则认为握手成功。

服务器结束响应

       服务器收到Client Key Exchange报文后,使用自己的密钥对Pre-master Secret进行解密,然后根据三个随机数和协商的加密算法,计算出会话密钥;

       服务器收到客户端发来的Finished报文,用会话密钥解密报文,并结合之前接收到所有报文生成的Hash值,对Finished报文进行验证,并且也会以同样的方式向客户端发送ChangeCipherSpecEncrypted Handshake Message报文,供客户端验证。

       根据之前的握手信息,如果客户端和服务器都能对Finished报文验证通过,则说明握手通道建立成功,之后双方使用之前协商好的加密方式进行通信。

连接断开

如果客户端断开连接,会向服务器发送close_notify报文。

3.3 数据完整性验证

 以上流程中,应用层发送数据时,都会附加一个叫MAC(Message Authentication Code,消息认证码算法)的报文摘要,MAC能查知报文是否遭到篡改,保证报文数据的完整性。MAC是含有密钥的散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加入了密钥。

Android网络编程学习笔记(一)_第6张图片
MAC算法

4 要点解析 

4.1 Cookie

       用于在连接之间存储持久的客户端状态,cookie在请求和响应报文中写入Cookie信息来控制客户端的状态,只能是非空白符的ASCII文本,不能包含逗号或分号

Set-Cookie/Cookie:设置Cookie,客户端根据该字段信息来保存Cookie,当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务端收到Cookie后,会去检查究竟是哪一个客户端发送来的请求,然后对比记录,得到之前的状态信息。

Max-Age:设置Cookie经过指定时间后过期,过期后,浏览器从缓存中删除这个Cookie

4.2  会话密钥重用

SSL/TLS握手过程比较繁琐,同时非对称加解密性能比对称密钥要差得多;如果每次重建连接时都需要进行一次握手会产生较大开销,因此有必要实现会话的重用以提高性能。

常用的方式包括:

SessionID(RFC 5246):客户端和服务端同时维护一个会话ID和会话数据状态;重建连接时双方根据sessionID找到之前的会话密钥实现重用;

SessionTicket(RFC 5077):由服务端根据会话状态生成一个加密的ticket,并将key也发给客户端保证两端都可以对其进行解密。该机制相较sessionID的方式更加轻量级,服务端不需要存储会话状态数据,可减轻一定压力

4.3 证书的校验

校验步骤:

1)检查数字签名:数字签名通过数字摘要算法生成并通过私钥加密传输,对端公钥解密;

2)CA链授权检查

3)证书过期及激活时间检查

数字摘要的计算图示

Android网络编程学习笔记(一)_第7张图片

参考:

https://www.cnblogs.com/qdhxhz/p/8468913.html

https://www.jianshu.com/p/e634784e7b00

https://www.cnblogs.com/littleatp/p/6219630.html

https://cloud.tencent.com/developer/article/1115445

https://www.jianshu.com/p/07a1e362e1ba

你可能感兴趣的:(Android网络编程学习笔记(一))