当前位置: 首页 > news >正文

HTTP协议解析:Session/Cookie机制与HTTPS加密体系的技术演进(二)

一.Cookie与Session

1.1Cookie 

        HTTP Cookie(也称为 Web Cookie、 浏览器 Cookie 或简称 Cookie) 是服务器发送到用户浏览器并保存在浏览器上的一小块数据, 它会在浏览器之后向同一服务器再次发起请求时被携带并发送到服务器上。 通常, 它用于告知服务端两个请求是否来自同一浏览器, 如保持用户的登录状态、 记录用户偏好等。

        比如当我们访问b站的网页端首页时,这里以windows自带的edge浏览器为例,点击url输入框中的锁图标。打开cookie与站点数据:

        当然在此之前是已经登录的状态,当我们把这些Cookie数据删除之后,ctrl + f强制刷新当前页面,会发现此时需要我们重新登录。为什么会这样,我们来从他的工作原理来解释:

1.1.1Cookie的工作原理 

  • 当用户第一次访问网站时, 服务器会在响应的 HTTP 头中设置 Set-Cookie字段, 用于发送 Cookie 到用户的浏览器。
  • 浏览器在接收到 Cookie 后, 会将其保存在本地(通常是按照域名进行存储) 。
  • 在之后的请求中, 浏览器会自动在 HTTP 请求头中携带 Cookie 字段, 将之前保存的 Cookie 信息发送给服务器。 

我们使用之前的Http代码添加一个响应报头Cookie: 

std::string Serialize()
{std::string status_line = _version + gspace + std::to_string(_code) + gspace + _desc + glinespace;std::string resp_header;_headers["Set-Cookie"] = "zhangsan=123456";for (auto &header : _headers){std::string line = header.first + glinesep + header.second + glinespace;resp_header += line;}return status_line + resp_header + _blankline + _text;
}

当没有设置响应报头时,浏览器访问我们自己的服务器不会有Cookie数据:

        设置之后便可以看到如下Cookie数据,同时也可以注意到浏览器的请求报头中也有了Cookie的信息:

        所以我们上面看到的啊b的Cookie的设置也是同理,如果说我们想要设置多个Cookie数据,可以多添加几个Set-Cookie报头。

1.1.2Cookie分类

        Cookie简单些来说可以分为两类,内存级以及文件级。前者一般是使用浏览器时保存在浏览器的内存中,后者则是以单独的文件形式存储在电脑中,一般会设置过期时间,到期自动删除。

更严谨一些是这样分类的:

  • 会话 Cookie( Session Cookie) 在浏览器关闭时失效。
  • 持久 Cookie( Persistent Cookie)带有明确的过期日期或持续时间,可以跨多个浏览器会话存在。
  • 如果 cookie 是一个持久性的 cookie, 那么它其实就是浏览器相关的, 特定目录下的一个文件。 但直接查看这些文件可能会看到乱码或无法读取的内容,因为 cookie 文件通常以二进制或 sqlite 格式存储。 一般我们查看, 直接在浏览器对应的选项中直接查看即可。

Cookie的用途也有很多:

  • 用户认证和会话管理(最重要)
  • 跟踪用户行为
  • 缓存用户偏好等
  • 比如在 chrome 浏览器下, 可以直接访问: chrome://settings/cookies

        但由于Cookie是保存在客户端的,对于大多数的客户端用户一般没有较强的意识去防范Cookie文件的盗取,此时则需要结合Session使用。当然这个我们后面再说,毕竟Cookie现在我们也只是知道了个皮毛,我们先来深入的认识下Cookie:

1.1.3认识Cookie

Set-Cookie可以用来进行为浏览器设置Cookie值,不多赘述,Set-Cookie的格式如下:

Set-Cookie: <name>=<value>
其中 <name> 是 Cookie 的名称, <value> 是 Cookie 的值。

完整的一个Cookie示例如下:

Set-Cookie: username=peter; expires=Thu, 18 Dec 2024 12:00:00
UTC; path=/; domain=.example.com; secure; HttpOnly

        时间格式必须遵守 RFC 1123 标准, 具体格式样例: Tue, 01 Jan 2030 12:34:56 GMT 或者 UTC(推荐)。GMT与UTC时间读者可自行搜索了解。我们在这里简单说一下原因,因为世界各地的时区不尽相同,所以要有一个标准时间,这个标准时间传到浏览器时浏览器会根据当前主机时区自动计算主机所在地区时间。以规避不同地区时间差导致的通信问题。

关于时间的解释:

  • Tue: 星期二(星期几的缩写)
  • ,: 逗号分隔符
  • 01: 日期(两位数表示)
  • Jan: 一月(月份的缩写)
  • 2030: 年份(四位数)
  • 12:34:56: 时间(小时、 分钟、 秒)
  • GMT: 格林威治标准时间(时区缩写)

关于其他可选属性的解释: 

  • expires=<date>: 设置 Cookie 的过期日期/时间。 如果未指定此属性, 则 Cookie 默认为会话 Cookie, 即当浏览器关闭时过期。
  • path=<some_path>: 限制 Cookie 发送到服务器的哪些路径。 默认为设置它的路径。也就是说只有客户端访问我们特定的页面时,才能获取我们Set-Cookie设置的Cookie值。
  • domain=<domain_name>[了解即可]: 指定哪些主机可以接受该 Cookie。 默认为设置它的主机。
  • secure[了解即可]: 仅当使用 HTTPS 协议时才发送 Cookie。 这有助于防止Cookie 在不安全的 HTTP 连接中被截获。
  • HttpOnly[了解即可]: 标记 Cookie 为 HttpOnly, 意味着该 Cookie 不能被客户端脚本(如 JavaScript) 访问。 这有助于防止跨站脚本攻击(XSS) 。

1.1.4Cookie的生命周期与安全性考虑

生命周期: 

  • 如果设置了 expires 属性, 则 Cookie 将在指定的日期/时间后过期。
  • 如果没有设置 expires 属性, 则 Cookie 默认为会话 Cookie, 即当浏览器关闭时过期。 

安全性考虑: 

  • 使用 secure 标志可以确保 Cookie 仅在 HTTPS 连接上发送, 从而提高安全性。
  • 使用 HttpOnly 标志可以防止客户端脚本(如 JavaScript) 访问 Cookie,从而防止 XSS 攻击。
  • 通过合理设置 Set-Cookie 的格式和属性, 可以确保 Cookie 的安全性、 有效性和可访问性, 从而满足 Web 应用程序的需求。  

所以单独使用Cookie,我们会发现有几个问题:

  1. 我们写入的是测试数据, 如果写入的是用户的私密数据呢? 比如, 用户名密码,浏览痕迹等。
  2. 本质问题在于这些用户私密数据在浏览器(用户端)保存, 非常容易被人盗取, 更重要的是, 除了被盗取, 还有就是用户私密数据也就泄漏了。  

为了尽可能减小这种安全隐患,此时就需要用到Session了。

1.2 Session 

1.2.1 Session是什么? 

        HTTP Session 是服务器用来跟踪用户与服务器交互期间用户状态的机制。 由于 HTTP协议是无状态的(每个请求都是独立的) , 因此服务器需要通过 Session 来记住用户的信息。
它的工作原理如下: 

  • 当用户首次访问网站时, 服务器会为用户创建一个唯一的 Session ID, 并通过Cookie 将其发送到客户端。
  • 客户端在之后的请求中会携带这个 Session ID, 服务器通过 Session ID 来识别用户, 从而获取用户的会话信息。
  • 服务器通常会将 Session 信息存储在内存、 数据库或缓存中。

        通俗点来说其实就好比我们去比如说健身房办卡,第一次办卡时需要我们设置自己卡账户的Cookie,也就是账号密码。办完之后会给我们一张卡,以后我们每次来不再需要输入Cookie,直接使用卡便能进健身方锻炼,此时这张卡就是Session。

        迁移到我们自己写的Http服务器,其实就是在我们的服务器中多维护了一张Session的哈希表,这个哈希表键值为Session,Value为用户的Cookie结构体。当用户第一次访问服务器时,由于没有注册,所以此时用户会上传自己账户的账号密码,我们服务器会将用户的账号密码存入设置好的Cookie结构体中,同时通过哈希函数为用户设置一个非重复的Session ID,然后使用Set-Cookie返回给用户该Session ID。下次用户再访问服务器时,浏览器直接提交Session ID服务器便能通过哈希表索引到用户信息从而通过验证。

1.2.2 对Session的安全性的讨论

        这时候就会有人说了,Session不是照样存储在客户端吗,那我盗取了不直接就能像Cookie那样登录帐号了吗。

        确实,但我们发现,此时Cookie是存储在服务器的,也就是说,用户的个人信息隐私在服务端被保护着。虽然Session仍然可以被盗取,但服务端解决方法就多了去了,比如最简单的,当服务端检测到用户当前登录位置与上次不同,会直接将用户的Session ID废弃,然后让用户重新输入账号密码或手机验证登录。由于服务端是专业的工程师维护的,正所谓专业的人做专业的事,此时用户隐私泄露这种安全隐患就被极大程度降低了。

1.2.3 Session的超时失效和用途 

超时和失效: 

        Session 可以设置超时时间, 当超过这个时间后, Session 会自动失效。服务器也可以主动使 Session 失效, 例如当用户登出时。

用途:

  • 用户认证和会话管理
  • 存储用户的临时数据(如购物车内容)
  • 实现分布式系统的会话共享(通过将会话数据存储在共享数据库或缓存中)

1.3 总结 

        HTTP Cookie 和 Session 都是用于在 Web 应用中跟踪用户状态的机制。 Cookie 是存储在客户端的, 而 Session 是存储在服务器端的。 它们各有优缺点, 通常在实际应用中会结合使用, 以达到最佳的用户体验和安全性。

TIPS: 

        favicon.ico 是一个网站图标, 通常显示在浏览器的标签页上、 地址栏旁边或收藏夹中。 这个图标的文件名 favicon 是 "favorite icon" 的缩写, 而 .ico 是图标的文件格式。浏览器在发起请求的时候, 也会为了获取图标而专门构建 http 请求, 我们不管它。

二.HTTPS协议

        HTTPS 也是一个应用层协议。是在 HTTP 协议的基础上引入了一个加密层。由于HTTP 协议内容都是按照文本的方式明文传输的。这就导致在传输过程中出现一些被篡改的情况。

        在介绍HTTPS的工作原理之前,我们先来谈谈什么是加密,为什么要加密,常见的加密方式有哪些:

2.1加密 

2.1.1什么是加密 

        加密就是把明文 (要传输的信息)进行一系列变换,生成密文。解密就是把密文再进行一系列变换, 还原成明文。在这个加密和解密的过程中,往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为密钥。比如DES(对称密钥),RSA(非对称密钥)等。

        加密解密到如今已经发展成一个独⽴的学科: 密码学。而密码学的奠基人, 也正是计算机科学的祖师爷之一,艾伦·⻨席森·图灵。

2.1.2 为什么要加密 

        我们以臭名昭著的运营商劫持为例子,运营商劫持(Carrier Hijacking)是指互联网服务提供商(ISP)利用其网络控制权,非法拦截、篡改或重定向用户的网络流量,通常用于插入广告、推广内容或监控用户行为。 

它常见的劫持有如下几种: 

  • DNS劫持:将用户访问的域名解析到错误的IP地址(例如跳转到广告页面)。

  • HTTP劫持:在网页中注入广告代码或弹窗(如HTTP响应被篡改)。

  • HTTPS降级:强制将加密连接(HTTPS)转为明文(HTTP),便于拦截。

        因为运营商在服务端与客户端通常为中间人的角色。所以无论是客户端发往服务端的报文还是服务端发往客户端的报文。都会经手运营商,如果我们的报文是HTTP明文的话,运营商便可以直接篡改明文数据。最典型的案例就是我们要下载steam时,如果是非官方网站,就极有可能导致我们原本想下载的是steam,结果下载完发现下成了steam管家。

        这还只是轻的,如果是想要盗取我们个人信息的黑客成为了中间人,只要我们使用明文报文传输,那我们的信息便会被他人一览无余的盗取。所以在互联网上, 明文传输是比较危险的事情!!!HTTPS 就是在 HTTP 的基础上进行了加密, 进一步的来保证用户的信息安全。

2.1.3 常见的加密方式

1.对称加密

        采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密,对于对称加密加密和解密所用的密钥是相同的。

        常见对称加密算法(了解): DES、 3DES、 AES、 TDEA、 Blowfish、 RC2 等。特点:算法公开、计算量小、加密速度快、加密效率高。

        对称加密其实就是通过同一个 "密钥" , 把明文加密成密文, 并且也能把密文解密成明文。一个简单的对称加密, 按位异或,假设 明文 a = 1234, 密钥 key = 8888,则加密 a ^ key 得到的密文 b 为 9834。然后针对密文 9834 再次进行运算 b ^ key,得到的就是原来的明文 1234。(对于字符串的对称加密也是同理,每一个字符都可以表示成一个数字)当然,按位异或只是最简单的对称加密。 HTTPS 中并不是使用按位异或。

2.非对称加密

        需要两个密钥来进行加密和解密,这两个密钥是公开密钥(public key,简称公钥)和私有密钥(private key,简称私钥)。常见非对称加密算法(了解): RSA, DSA, ECDSA。

        非对称加密的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。非对称加密要用到两个密钥, 一个叫做 "公钥", 一个叫做 "私钥"。公钥和私钥是配对的. 最大的缺点就是运算速度非常慢,比对称加密要慢很多。

        我们对于公钥和私钥可以正着使用,即通过公钥对明文加密, 变成密文,通过私钥对密文解密, 变成明文。也可以反着用,通过私钥对明文加密, 变成密文,通过公钥对密文解密, 变成明文。

2.1.4数据摘要(数据指纹) 

        数字指纹(数据摘要),其基本原理是利用单向散列函数(Hash 函数)对信息进行运算,生成一串固定长度的数字摘要。数字指纹并不是一种加密机制,但可以用来判断数据有没有被篡改。

        摘要常见算法:有 MD5、 SHA1、 SHA256、 SHA512 等,算法把无限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)。摘要的特征-和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。

        同时数据摘要经过加密便可以形成数字签名,这个我们到后面再细说。

2.2 HTTPS工作流程的讨论

        从上面我们可以得出4种加密方式,一只使用对称加密,二只使用非对称加密,三双方都使用非对称加密,四非对称加密+对称加密。但这四种方法都行不通。下面我们来一一解释为什么。

2.2.1只使用对称加密 

        其实这种方法感觉上是最安全的。因为密钥只有服务端与客户端持有。只要密钥不被破解,报文的内容也就不可能泄露。但通常我们一个服务端对应着成千上百万客户端,那每一个与服务端建立联系的客户端服务端都需要保存维护通信的密钥。

        这样会造成大量的资源损耗。所以我们一般是在通信开始时与客户端先协商密钥,双方都协商好本次通信的密钥之后再进行通信。那密钥传输到对端的时候需不需要加密,要。那这就是典型的鸡生蛋蛋生鸡的问题了。显然只是用对称加密是行不通的。

2.2.2只使用非对称加密,双方均使用非对称加密与非对称加密+对称加密

        因为这三者的破解方式是差不多的,所以我们挑其中一个便能理解另外两个为什么行不通了。我们就以非对称加密+对称加密为例:

        乍一看好像还是那么回事,即确保了密钥能够传输到对端。又可以避免使用大量的非对称解密造成资源损耗过多。但如果客户端一开始收到的是中间人伪造的公钥呢?

我们称这种攻击方式为Man-in-the-MiddleAttack,简称“MITM 攻击“。
中间人攻击_百度百科

        我们发现,问题本质出在哪里了呢? 就是客户端无法确定收到的含有公钥的数据报文, 就是目标服务器发送过来的。这时候就需要使用到证书了。

2.3证书 

通常我们的浏览器都会存储各种各样的证书,那么证书是什么?

        如果有搞过博客网站的同学肯定知道,我们在网站的注册时通常需要申请证书,如果不申请当别人想要访问我们的博客网站时就会弹出如下界面:

        对于证书,通俗理解就好比是我们如果从事某些工作时,需要我们提交健康证明。从事餐饮行业时,需要有营业执照。也就是说,证书是官方的权威可信任组织,对网站的安全性审核之后,确保了网站是安全的后给予网站的一种证明。

        更详细严谨些,服务端在使用 HTTPS 前, 需要向 CA 机构申领一份数字证书, 数字证书里含有证书申请者信息、 公钥信息等。 服务器把证书传输给浏览器, 浏览器从证书里获取公钥就行了, 证书就如身份证, 证明服务端公钥的权威性。

2.3.1从证书申请看网站安全机制

        这是一张网站申请证书,并使用申请的证书来确保自己传到对端的密钥不被篡改以达成服务与客户端安全通信的流程示例。也就是我们给出的第五种方案-非对称加密+对称加密+CA证书。在介绍我们第五种加密方案流程之前,我们先来认识下数据签名。

1.数据签名

        签名的形成是基于非对称加密算法的, 注意, ⽬ 前暂时和 https 没有关系, 不要和https 中的公钥私钥搞混了。

        当服务端申请 CA 证书的时候, CA 机构会对该服务端进行审核, 并专⻔为该网站形成数字签名, 过程如下:

  1. CA 机构拥有非对称加密的私钥 A 和公钥 A'
  2. CA 机构对服务端申请的证书明文数据进行 hash, 形成数据摘要
  3.  然后对数据摘要用 CA 私钥 A'加密, 得到数字签名 S

        服务端申请的证书明文和数字签名 S 共同组成了数字证书, 这样一份数字证书就可以颁发给服务端了。

2.方案 5 - 非对称加密 + 对称加密 + 证书认证

        此时的安全性就比较高了。在客户端和服务器刚一建⽴连接的时候, 服务器给客户端返回一个 证书, 证书包含了之前服务端的公钥, 也包含了网站的身份信息:

        接下来客户端进行认证,当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的):

  • 判定证书的有效期是否过期
  • 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
  • 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的

 那我们说这个流程中间人能否掉包证书呢,难度很大:假如说此时中间人篡改了证书的明文

  • 由于他没有 CA 机构的私钥, 所以无法 hash 之后用私钥加密形成签名, 那么也就没法办法对篡改后的证书形成匹配的签名
  • 如果强行篡改, 客户端收到该证书后会发现明文和签名解密后的值不一致, 则说明证书已被篡改, 证书不可信, 从而终止向服务器传输信息, 防止信息泄露给中间人

        也就是说中间人只有获得了CA认证机构的私钥,才能够篡改证书的明文,或者说把密钥破解了。所以难度很大。 

那如果说中间人整个掉包证书呢?

  1. 因为中间人没有 CA 私钥, 所以无法制作假的证书。
  2. 所以中间人只能向 CA 申请真证书, 然后用自己申请的证书进行掉包。
  3. 这个确实能做到证书的整体掉包, 但是别忘记, 证书明文中包含了域名等服务端认证信息, 如果整体掉包, 客户端依旧能够识别出来。
  4. 永远记住: 中间人没有 CA 私钥, 所以对任何证书都无法进行合法修改, 包括自己。

        也就是说,因为CA机构的公钥所有浏览器都认识,你中间人想整体掉包用自己生成的非对称密钥,人家客户端拿着CA机构的公钥根本不认识你加密的报文,自然就知道证书被篡改了。 

2.4 总结

HTTPS 工作过程中涉及到的密钥有三组:

        第一组(非对称加密): 用于校验证书是否被篡改。服务器持有私钥(私钥在形成 CSR 文件与申请证书时获得), 客户端持有公钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥)。 服务器在客户端请求时, 返回携带签名的证书。客户端通过这个公钥进行证书验证,保证证书的合法性, 进一步保证证书中携带的服务端公钥权威性。
        第⼆组(非对称加密): 用于协商生成对称加密的密钥。 客户端用收到的 CA 证书中的公钥(是可被信任的)给随机生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解密获取到对称加密密钥。

        第三组(对称加密): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密。

        其实一切的关键都是围绕这个对称加密的密钥,其他的机制都是辅助这个密钥工作的。第⼆组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器。第一组非对称加密的密钥是为了让客户端拿到第⼆组非对称加密的公钥。


 

相关文章:

  • 基于STM32、HAL库的PCM3060PWR 音频接口芯片驱动程序设计
  • UDP协议详细讲解及C++代码实例
  • 转发多台px4仿真UDP数据到地面站
  • KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache
  • sqlserver免费版每天备份数据库
  • 【计算机网络】3数据链路层②
  • 数据结构(一) 绪论
  • 进程与线程:07 CPU调度策略
  • 黑马Java基础笔记-10
  • Spring框架请求注解
  • Java键盘鼠标事件监听器(鼠标)MouseListener、MouseMotionListener、MouseWheelListener和(键盘)keyListener
  • 科学养生,开启健康生活
  • Spring Security与SaToken的对比
  • 机试刷题:进制转换3
  • 蓝桥杯题库经典题型
  • 【Linux】操作系统入门:冯诺依曼体系结构
  • Python作业练习3
  • 【愚公系列】《Manus极简入门》036-物联网系统架构师:“万物互联师”
  • mysql环境配置
  • do while
  • 山东:小伙为救同学耽误考试属实,启用副题安排考试
  • 上海团队在医学顶刊连发两文,率先提出“证据污染”循证概念
  • 这个“超强致癌细菌”,宝宝感染率高达40%,预防却很简单
  • 明查|印度空军“又有一架战机被巴基斯坦击落,飞行员被俘”?
  • 商务部召开外贸企业圆桌会:全力为外贸企业纾困解难,提供更多支持
  • 飙升至熔断,巴基斯坦股市两大股指收盘涨逾9%