android http\https学习笔记

参考文档

阮一峰的博客:
https://www.ruanyifeng.com/blog/2016/08/http.html
https://www.runoob.com/w3cnote/http-vs-https.html
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
http://www.ruanyifeng.com/blog/2016/08/migrate-from-http-to-https.html
http的缓存机制
https://www.cnblogs.com/chenqf/p/6386163.html
Android中使用https
https://juejin.cn/post/6844903470584037383

http

tcp协议的三次握手

要先回忆下tcp协议的三次握手过程, 因为无论是http还是https, 都需要建立在tcp建立连接之后.
在这里插入图片描述
形象一点表述就是
在这里插入图片描述
具体里面的交互, syn, ack字段什么, 我觉得不重要, 到时候查资料就可以了, 关键是要理解这个过程

http协议简史

文档 https://www.ruanyifeng.com/blog/2016/08/http.html

  • 现在最流行的版本是http/1.1版本, 之前有发布过http/0.9 http/1.0版本. 最新的版本是http/2版本.
  • http/0.9 只有一个GET命令, 服务端只能回复一个html格式的回复
  • http/1.0 引入POST与HEAD命令, 要求必须有头信息, 增加了状态码, 多字符集, 多部分发送(multi-part type), 权限, 缓存, 内容编码等
  • http/1.0 有一个最大的缺点是, 每个TCP连接只能发送一次请求, 发送请求完毕, 连接就关闭, 如果还要请求资源, 就必须再重新建立一个连接. 所以成本很高
  • http/1.1修改了上述问题, 引入了持久连接的概念, TCP连接默认不关闭, 可以被多个请求复用. 当客户端和服务端发现对方一段时间没有活动, 就主动关闭连接. 对于同一域名, 大多数浏览器允许同时建立6个持久连接.
  • http/1.1版本引入了管道机制(pipelinling), 客户端可以同时发送多个请求, 但是服务端必须要按照顺序来回应请求, 那这个时候就会面临一个问题, 我怎么知道这个数据包属于哪次http请求.http/1.1有两种解决方案.
  1. 定义一个Content-Length字段, 声明本次回应的长度.
  2. 采用分块传输, Transfer-Encoding: chunked. 每次http内容发送完毕之后, 发送一个Content-Length:0的数据包, 标明这次已经请求已经发送完毕.
  3. (但是以上就能解决所有的问题吗? 因为客户端是可以同时发送多个请求的, 那么如果后发的请求先到服务端了怎么办? 这种顺序怎么保证? 目前没有看到资料, 可能要深入到http和tcp协议里面看下
  • http/1.1有一个缺点, 就是服务端是顺序处理的, 如果一个请求处理的慢了, 就会形成堵塞. 为了解决这个问题, 引入了http/2
  • http/2是2015年才发布的, 采用了二进制协议, 即头信息和数据体都要求是二进制, 并且统称为"帧",
  • http/2中, 采用多工机制, 即客户端和服务端都可以同时发送多个请求, 那么怎么区分每个回复的数据包呢. 当然是引入一个数据流的id…
  • 我还是不太明白, http/2中怎么保证请求和回复一一对应, 当然, http/1.1中也有这个问题, 待查阅资料.

http协议那些头

  • Connection: keep-alive\close http/1.1中默认为keep-alive, 表示不关闭TCP链接, 当需要关闭的时候, 可以发一个close
  • Content-Encoding: gzip\compress\deflate, 数据的压缩方法
  • Content-Type: text/html; charset=utf-8 . 数据格式
  • Accept: / 客户端声明自己支持哪些数据格式

http协议的缓存机制

这一片文章写得太好了, 深入浅出 https://www.cnblogs.com/chenqf/p/6386163.html
总结下这篇文章中的知识点

  • 客户端(浏览器)是有一个缓存数据库的, 根据一定策略, 要么从缓存数据库中取数据, 要么从服务端取数据, 要么拿了客户端数据去和服务端的比较
  • 主要是通过Cache-Control字段来标明缓存策略的, 取值如下
  1. private 客户端可以缓存
  2. public 客户端和代理服务器都可以缓存
  3. max-age=xxx: 缓存的内容会在xxx秒之后失效
  4. no-cache: 使用对比缓存
  5. no-store: 不使用缓存.
  • 对比缓存 客户端本次存储缓存, 下次请求时, 带上缓存标识, 服务端如果发现没有更新, 就直接返回304和头部分, 通知客户端你用缓存就行, 我不给你新数据了, 缓存标识分为下面几类
  1. Last-Modified/If-Modified-Since. 服务器通过Last-Modified字段来告诉客户端资源的最后修改时间, 下次客户端请求时, 会通过If-Modified-Since把这个时间带上, 服务端用来比较
  2. Etag/If-None-Match , Etag是服务端返回的唯一表示, If-None-Match就是要带上这个标识

https

https协议的握手过程

参考文档 http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html

https协议其实就是http+TLS协议, 在交互之前, 除了TCP的握手之外, 要完成TLS协议的握手, 具体规则如下
在这里插入图片描述
握手分为四个阶段

1. 客户端向服务端发出加密通信的请求, 也被叫做ClientHello请求

客户端发送以下信息

  1. 支持的协议版本
  2. 一个客户端发出的随机数, 稍后用于生成"对话秘钥"
  3. 支持的加密方法, 比如说RSA公钥加密
  4. 支持的压缩方法

2. 服务器收到客户端请求之后发出回应, 也叫做ServerHello

该回应包含以下信息

  1. 确定使用的加密通信版本
  2. 一个服务端生成的随机数, 稍后用于生成"对话秘钥"
  3. 确认使用的加密方法, 比如说RSA公钥加密
  4. 服务器证书, 即CA证书

需要注意的是

  1. 上述CA证书中只包含公钥
  2. 如果服务器需要确认客户端的身份, 还会包含一项请求, 要求客户端提供"客户端证书", 比如, 金融机构往往只允许认证客户端接入自己的网络, 就会向客户端要求提供USB秘钥, 里面汉堡一张客户端的证书.

3. 客户端回应

客户端收到服务器的回应之后, 会首先验证下服务器的根证书, 如果证书不是可信机构颁布的, 或者证书中的域名与实际域名不一致, 或者证书已经过期等等, 就会给访问者一个提示, 提示用户是否继续访问(如之前12306的证书就是自签发的证书, 浏览器不能识别)
如果没有问题, 客户端就会从服务端的证书中取出公钥, 然后, 向服务端发送以下信息

  1. 一个随机数, 该随机数用CA证书中的公钥加密, 防止被窃听
  2. 编码改变通知, 表示随后的信息都将用双方商定的加密方法和秘钥发送
  3. 客户端握手结束通知.

其中, 上述中的随机数, 是整个握手阶段出现的第三个随机数, 通过之前的三个随机数一起生成"会话秘钥"

4. 服务端最后的响应

服务端收到客户端的第三个请求后, 技术生成会话秘钥, 然后向客户端发送以下信息

  1. 编码改变通知, 表示税后的信息都将用双方商定的加密方法和秘钥发送
  2. 服务器握手结束通知, 表示服务器的握手阶段已经结束

接下来, 双方进入到加密通信阶段, 完全使用普通的http协议. 只不过这些都是用会话密码对称加密内容

上面的整个流程看完之后, 可能还是会有一些疑问, 下面是我的一些理解(不一定正确, 欢迎指正)

Q1: 为什么要使用会话秘钥

加密通信阶段使用会话秘钥, 可以加快加密的速度, 这是个是对应加密的. 而握手阶段采用的公钥加密, 属于不对称加密, 比较耗费时间

Q2: 为什么要用CA证书, 为什么可以防备中间人攻击

客户端预制了一部分证书, 所以CA证书必须要由特定结构来进行签发, 校验域名等信息, 所以可以防备中间人攻击

Q3: 整个流程看下来, 其实基本上主要是客户端校验服务端的身份

http与https协议的区别

概括一下区别

  1. HTTP是明文传输的, 数据都是未加密的, 安全性较差. HTTPS数据传输过程是加密的, 安全性较好
  2. 使用HTTPS协议需要用到CA证书, 一般免费证书比较少, 因而需要一定的费用.
  3. HTTP页面响应速度比HTTPS较快(理论上), 因为HTTPS需要建立TLS握手的过程
  4. 使用的默认端口不一样, http是80端口, https默认是443端口
  5. https是构建在ssl/tls之上的http协议, 所以, 要比http更耗费服务器资源.

上述http页面的响应速度比https快, 这个如果要细分, 是可以分情况的
参看这篇文章
https协议的七个误解

第一次请求, https肯定比http要慢
之后请求, 因为连接已经建立起来了, 所以两者相差无几, https略微多一丁点
部分情况下, https比http要快, 因为网关可能会截取分析网络通信, https通信因为加密了, 网关无法分析, 可能就直接放行了

CA证书

怎么理解CA证书
参看这篇文章吧 https://www.cnblogs.com/handsomeBoys/p/6556336.html

直接把内容贴过来

看过一些博客,写的比较形象具体。
◇ 普通的介绍信
想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 B 公司的所有人都不认识他,他咋办捏?常用的办法是带公司开的一张介绍信,在信中说:兹有张三先生前往贵公司办理业务,请给予接洽…云云。然后在信上敲上A公司的公章。
张三先生到了 B 公司后,把介绍信递给 B 公司的前台李四小姐。李小姐一看介绍信上有 A 公司的公章,而且 A 公司是经常和 B 公司有业务往来的,这位李小姐就相信张先生不是歹人了。
这里,A公司就是CA证书
◇ 引入中介机构的介绍信
  好,回到刚才的话题。如果和 B 公司有业务往来的公司很多,每个公司的公章都不同,那前台就要懂得分辨各种公章,非常滴麻烦。所以,有某个中介公司 C,发现了这个商机。C公司专门开设了一项“代理公章”的业务。
  今后,A 公司的业务员去 B 公司,需要带2个介绍信:
  介绍信1
  含有 C 公司的公章及 A 公司的公章。并且特地注明:C 公司信任 A 公司。
  介绍信2
  仅含有 A 公司的公章,然后写上:兹有张三先生前往贵公司办理业务,请给予接洽…云云。
  某些不开窍的同学会问了,这样不是增加麻烦了吗?有啥好处捏?
  主要的好处在于,对于接待公司的前台,就不需要记住各个公司的公章分别是啥样子的;他/她只要记住中介公司 C 的公章即可。当他/她拿到两份介绍信之后,先对介绍信1的 C 公章,验明正身;确认无误之后,再比对介绍信1和介绍信2的两个 A 公章是否一致。如果是一样的,那就可以证明介绍信2是可以信任的了。

感觉CA证书有点像一个信任链. A信任B, B信任C, B信任C. 作为客户端, 我只需要保留A机构的信息就可以了. CA证书体现出信任链关系, 让客户端知道C最终是可以信任的

Android中的http与https

通常的使用姿势

参看文档
android官方网络配置
通常来说, 不要什么额外的配置, 直接默认使用https就好

但是有人希望使用http, 在Android P版本(28)之后, 按照官方的说法, 是限制客户端使用http了. 除非做以下修改
定义一个network_security_config.xml文件, 内容如下

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

AndroidManfiest的application中加上一下配置

    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config"
        ...
        />

这里要澄清的一点是, Google官方是说Android P版本之后默认不让使用http了, 但是亲测之后发现可以. 走读了下源码, 该部分是有系统的DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED字段控制的, true表示允许使用http. 目前Android源码里, 这个值是true.

所以没有明白这个逻辑, 可能google只是"吓唬"我们的? 为了保险起见, 还是加上上面的network_security_config配置吧. 不多

使用自己签发的CA证书

参看文档
https://juejin.cn/post/6844903470584037383

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值