http

110 阅读14分钟

缓存

缓存的作用

  • 减少了冗余的数据传输,节省了网费。
  • 减少了服务器的负担, 大大提高了网站的性能
  • 加快了客户端加载网页的速度

缓存分类

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源重新下载。缓存的种类有很多,其大致可归为两类:

  • 私有缓存(例:浏览器缓存)

  • 共享缓存(例:代理缓存)

  • 强制缓存如果生效,不需要再和服务器发生交互,

  • 对比缓存不管是否生效,都需要与服务端发生交互

u40195mjop.png

secondcache.png

用户操作行为与缓存

v03kk4obhu.png

  • ETag(Entity Tag)是HTTP协议中用于Web缓存验证的一种机制,它允许客户端发出条件请求,以检查资源自上次请求后是否已更改。ETag有两种主要类型:弱ETag(weak ETag)和强ETag(strong ETag),它们在功能和用途上存在一些关键区别。

主要区别

  1. 内容匹配标准

    • 强ETag:要求两个资源表示的内容在字节级别上是完全相同的。这意味着除了内容本身外,所有其他实体字段(如Content-Language)也必须相同。强ETag的匹配非常严格,适用于需要精确控制内容一致性的场景
    • 弱ETag:仅要求两种资源表示在语义上是等效的,即它们在实际使用中是可以互换的。这意味着尽管资源表示可能不完全相同(例如,格式或编码的微小差异),但它们对于用户来说具有相同的功能或意义。弱ETag的匹配较为宽松,适用于内容可能动态生成或频繁变化的场景
  2. 格式表示

    • 在ETag的字符串表示中,弱ETag通过在标识符前添加“W/”前缀来区分。例如,弱ETag可能表示为“W/"etag-value"”,而强ETag则直接为“"etag-value"”。
  3. 应用场景

    • 强ETag:适用于需要精确控制资源一致性的场景,如文件下载、视频流等。在这些场景中,资源的任何微小变化都可能导致问题,因此强ETag的严格匹配机制非常有用。
    • 弱ETag:适用于内容可能频繁变化或动态生成的场景,如网页内容、搜索结果等。在这些场景中,弱ETag的宽松匹配机制可以减少不必要的资源传输,提高缓存效率。

示例

  • 强ETag示例"67ab430f76094d31b97decf2cb502d6f"
  • 弱ETag示例W/"67ab430f76094d31b97decf2cb502d6f"

浏览器中的操作对缓存的影响:

  • 强制刷新 – 当按下ctrl+F5来刷新页面的时候, 浏览器将绕过各种缓存(本地缓存和协商缓存), 直接让服务器返回最新的资源;
  • 普通刷新 – 当按下F5来刷新页面的时候,浏览器将绕过本地缓蹲来发送请求到服务器, 此时, 协商缓存是有效的
  • 回车或转向 – 当在地址栏上输入回车或者按下跳转按钮的时候, 所有缓存都生效

Cache-Control、Expires

Expires

指定缓存到期GMT的绝对时间,如果设了max-agemax-age就会覆盖expires。如果expires到期需要重新请求。

Cache-Control

Cache-Control:这个是http 1.1中为了弥补 Expires 缺陷新加入的。

对已缓存的内容进行控制:

Cache-control: public表示缓存的版本可以被代理服务器或者其他中间服务器识别。

Cache-control: private意味着这个文件对不同的用户是不同的。只有用户自己的浏览器能够进行缓存,公共的代理服务器不允许缓存。

Cache-control: no-cache意味着文件的内容不应当被缓存。这在搜索或者翻页结果中非常有用,因为同样的URL,对应的内容会发生变化。

其他相关控制字段:

max-age: 指定缓存过期的相对时间秒数,max-ag=0或者是负值,浏览器会在对应的缓存中把Expires设置为1970-01-01 08:00:00 。

s-maxage: 类似于max-age,只用在共享缓存上,比如proxy.

public: 通常情况下需要http身份验证的情况,响应是不可cahce的,加上public可以使它被cache。

no-cache: 强制浏览器在使用cache拷贝之前先提交一个http请求到源服务器进行确认。这对身份验证来说是非常有用的,能比较好的遵守 (可以结合public进行考虑)。它对维持一个资源总是最新的也很有用,与此同时还不完全丧失cache带来的好处),因为它在本地是有拷贝的,但是在用之前都进行了确认,这样http请求并未减少,但可能会减少一个响应体。

no-store: 告诉浏览器在任何情况下都不要进行cache,不在本地保留拷贝。

must-revalidate: 强制浏览器严格遵守你设置的cache规则。

proxy-revalidate: 强制proxy严格遵守你设置的cache规则。

用法举例: Cache-Control: max-age=3600, must-revalidate

其他标签

Content-Length:尽管并没有在缓存中明确涉及,Content-Length头部在设置缓存策略时很重要。某些软件如果不提前获知内容的大小以留出足够空间,则会拒绝缓存该内容。

Vary:缓存系统通常使用请求的主机和路径作为存储该资源的键。当判断一个请求是否是请求同样内容时,Vary头部可以被用来提醒缓存系统需要注意另一个附加头部。它通常被用来告诉缓存系统同样注意Accept-Encoding头部,以便缓存系统能够区分压缩和未压缩的内容

http字段

Transfer-Encoding

  • http 1.1添加的字段
  • 定义body在传输的时候采用什么方式编码来传输数据,
  • 这个字段通常用于指示是否采用分块传输编码(chunked encoding)以及其他可能的编码方式。
  • chunked是一种将body数据分成多个小块(chunks)的传输方式,每个小块的大小和内容长度是可变的。
    • 分块传输的优点:
      • 这种编码方式使得服务器可以逐步发送响应数据,而无需等待整个响应完全生成。这对于大文件或长时间运行的响应非常有用,因为它允许客户端在接收到部分响应时就开始处理它,而不需要等待整个响应完成
  • Transfer-Encoding字段通常会包含多个编码方式,它们按照优先级顺序排列,最优先的编码方式在前面
  • gzip:指示响应数据采用gzip压缩编码。客户端接收到响应后必须解压缩数据。示例:Transfer-Encoding: gzip
  • deflate:指示响应数据采用deflate压缩编码。客户端接收到响应后必须解压缩数据。示例:Transfer-Encoding: deflate
  • identity:表示响应数据没有经过任何传输编码,是原始数据。这是Transfer-Encoding的默认值,通常不需要显式指定。示例:Transfer-Encoding: identity
  • br:指示响应数据采用Brotli压缩编码。示例:Transfer-Encoding: br
  • compress:指示响应数据采用UNIX的compress压缩编码。这种编码方式相对较少使用。示例:Transfer-Encoding: compress

Connection

  • keep-alive 保持请求连接,以便后续请求复用
  • close 关闭请求,不服用连接

Keep-Alive

配合 Connection: Keep-Alive使用,指定保持连接的参数

  • Keep-Alive: timeout=2, max=100
    • timeout:都长时间后断开连接单位是s
    • max:断开前允许的请求数量 一个实例

一个跨域请求体:

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example

跨域请求响应体:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[…XML Data…]

Origin

  • 用途: 指示请求的来源(协议、域名和端口)。
  • 使用场景: 主要用于跨域请求(CORS),帮助服务器确定请求是否来自允许的来源。
  • 包含内容: 仅包含协议、域名和端口,不包含具体路径。
  • 假设你从 https://example.com/page.html 发起一个跨域请求到 https://api.example.com/data

referer

  • http://aa.com/ 首页中有有一个连接 http://www.baidu.com 连接,点击这个连接,referer会被设置为http://aa.com/

  • 防止csrf攻击

  • 防盗链

    • 比如有些网站不允许图片外链,只有自家的网站才能显示图片,外部网站加载图片就会报错。它的实现就是基于Referer字段的,如果该字段的网址是自家网址,就放行。
    • 将http请求发给服务器后,如果服务器要求必须是某个地址或者某几个地址才能访问,而你发送的referer不符合他的要求,就会拦截或者跳转到他要求的地址,然后再通过这个地址进行访问。
  • 设置Referer

    • <a> <area> <form> 可以直接设置rel="noreferrer"不发送Referer

      ```js
       <a href="..." rel="noreferrer" target="_blank">xxx</a>
      ```
      
    • 还有一种比较老式的技巧,但是非常有效,可以隐藏掉原始网址,谷歌和 Facebook 都在使用这种方法。链接的时候,不要直接跳转,而是通过一个重定向网址,就像下面这样。

      <a href="/exit.php?url=http%3A%2F%2Fexample.com">Example.com</a>
      
    • 其他设置方式

    // meta 标签设置
    <meta name="referrer" content="no-referrer">
    // 请求体色值
    Content-Security-Policy: referrer no-referrer;
    

https

  • http+TLS
    • TLS:Transport Layer Security
    • SSL: Secure Sockets Layer
    • SSL 是TLS的前身,TLS是SSL的标准

加密方法

  • 对称加密
    • AES
    • 采用协商的密钥对数据加密
  • 非对称加密
    • RSA
    • 身份认证和密钥协商
  • 完整性验证算法
    • MD5,SHA1,SHA256
    • 散列函数验证信息的完整性

对称加密

  • 相同的密钥可以用于信息的加密和解密,掌握密钥才能获取信息,能够防止信息窃听,通信方式是1对1
  • 对称加密需要共享相同的密码,密码的安全是保证信息安全的基础,服务器和多 个客户端通信,需要维持多个密码记录,且缺少修改密码的机制;
  • 优点:算法公开、计算量小、加密速度快、加密效率高。
  • 缺点:交易双方都使用同样钥匙,安全性得不到保证。 ba63c8102317810259322a1956064bd.png

非对称加密

  • 密钥成对出现,一般称为公钥(公开)和私钥(保密),公钥加密的信息只能私钥解开,私钥加密的信息只能公钥解开。因此掌握公钥的不同客户端之间不能互相解密信息,只能和掌握私钥的服务器进行加密通信,服务器可以实现1对多的通信,客户端也可以用来验证掌握私钥的服务器身份。
  • 非对称加密的特点是信息传输一对多,服务器只需要维持一个私钥就能够和多个客户端进行加密通信,但服务器发出的信息能够被所有的客户端解密,且该算法的计算复杂,加密速度慢
  • 只有服务器有私钥,所以黑客拿到公钥也没用。
  • 非对称加密效率低,结合对称加密一起使用:对称加密的秘钥用来加密数据,非对称加密用来协商秘钥
  • 客户端将对称加密的私钥发给服务端 03782ead8e501d6ea5079fea65b615f.png
  • 问题:如果网站被篡改了怎么办?
    • 这就是https出现的原因,过程与此类似,将发给客户端的公钥换成证书即可 146e44cef14983e63f52b8c1138c126.png

3ad464104d98ce6f1cae9efec4754c2.png

完整性验证

  • 常见的有 MD5、SHA1、SHA256,该类函数特点是函数单向不可逆(只能加密不能解密)、对输入非常敏感、输出长度固定,针对数据的任何修改都会改变散列函数的结果,用于防止信息篡改并验证数据的完整性
  • 在信息传输过程中,散列函数不能单独实现信息防篡改,因为明文传输,中间人可以修改信息之后重新计算信息摘要,因此需要对传输的信息以及信息摘要进行加密

证书的颁发

  • 为了保证服务端公钥安全传递到客户端

  • 客户端安全拿到公钥后,用公钥加密对称加密的私钥,发给服务端。

  • 服务端拿到对称加密的私钥后,就可以用私钥加密数据,在客户端之间发送信息了。 ad16caf7d866e374a7d84e696213ef0.png

  • 机器操作系统中预设了org_pub公钥

  • 加密步骤

    • 摘要 = MD5(serverInfo)
    • 签名 = org_pri(摘要)
  • 两次校验

    • org_pub用来验证证书是CA颁发的
    • 客户端拿到证书中的明文,使用同样的方式获取摘要,对比解密后的摘要和计算的摘要, 两者相同验证成功。
    • 黑客可能篡改CA机构证书的明文。例如换成黑客自己的公钥,黑客自己的地址等

认证方式

单向认证方式: 客户端认证服务端证书信息

1720766791625.png

1720766924280.png

  • 单向认证的SSL\TLS的握手过程
    • 1.客户端请求服务端,携带者自己支持的SS1\TLS版本信息、随机数等
    • 2.服务端将证书、服务端的SSL\TLS版本信息发送给客户端,并且将自己的公钥(server_pub)放到证书中
    • 3.客户端对证书进行验证,验证通过后,将自己支持的对称加密算法方案发送给服务端,供服务端选择
    • 4.服务端选择一个优质的算法方案,然后将选择的方法明文发送给客户端
    • 5.客户端生成一个随机字符串pre_master_secret,通过协商好的算法计算得出对称加密的密钥secret_key,然后利用服务端的公钥server_pub对pre_master_secret进行非对称加密,得到mi_secret_key数据,然后将这个数据发送给服务端
    • 6.服务端利用自己的私钥对mi_secret_key进行解密,得到pre_master_secret,然后通过协商好的算法对pre_master_secret进行加密得到密钥secret_key,然后利用选好的对称加密算法和secret_key对响应数据进行加密,然后发送给客户端
    • 7.客户端利用相同的对称加密算法和自己这一端保存的那个secret_key来解密得到响应数据
双向认证方式
  • 安全要求高的应用
  • 客户端(app等)也向CA机构申请证书,服务器端也要验证客户端的证书是否合法。

1720767654419.png

  • 双向认证比单向认证,主要是多了一个客户端的证书认证过程,和单向认证中客户端校验服务端证书的流程是一样的,双向认证一般用户对安全性要求非常高的场景中,比如区块链、银行支付U盾等。好,既然HTTPS的认证过程大家都已经明白了,应该就能够明白了为什么我们直接通过BP进行HTTPS数据包抓取的时候,有些数据抓不到,或者浏览器提示不安全的原因了,就是缺少证书或者证书验证不通过导致的,接下来我们回到BP抓取HTTPS数据包的那一节。

参考文章