HTTP到HTTPS的演化

我们不生产知识,我们只是互联网的搬运工 HTTP到HTTPS的演化 HTTP 由于是明文传输,所以安全上存在以下三个风险: 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。 篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。 冒充风险,比如冒充淘宝网站,用户钱容易没。 窃听风险 假设 A 想通过互联网向 B 发送消息。数据要经过互联网上各种各样的网络和设备才能到达 B 那里。 ​​ 数据可能会被第三者恶意窃听。 ​ 因此,我们需要给想要保密的数据加密。加密后的数据被称为“密文”。 ​ 把密文发送给 B。 ​ B 收到密文后,需要解除加密才能得到原本的数据。 ​​ 像这样对数据进行加密,就不用担心会被人窃听了。 共享秘钥加密 A 使用密钥加密数据。 ​ A 将密文发送给 B。​ B 收到密文后,使用相同的密钥对其进行解密。这样,B 就取得了原本的数据。只要是加密好的数据,就算被第三者恶意窃听也无须担心。 ​​ 实现共享密钥加密的算法有AES、DES等,其中 AES 的应用最为广泛。 ​​ 互联网两端的A 和 B 无法直接沟通,B 不知道加密时使用的是什么密钥。 A 需要通过某种手段将密钥交给 B。和密文一样,A 又在互联网上向 B 发送了密钥。 B 使用收到的密钥对密文进行解密。 但是,该密钥也有可能会被 X 窃听。这样一来,X 也可以使用密钥对密文进行解密了。 ​​ 为了解决这个问题,就需要使用公开秘钥加密(非对称秘钥加密) 公开秘钥加密 A 准备通过互联网向 B 发送数据 ​​ 首先,需要由接收方 B 来生成公开密钥和私有密钥,然后把公开密钥发送给 ...
2023年10月15日

网络通信-长连接与短连接

简单介绍长连接与短连接的优缺点。 短连接 client 向 server 发起连接请求 server 接到请求,双方建立连接 client 向 server 发送消息 server 回应 client 一次读写完成,此时双方任何一个都可以发起 close 操作 长连接 client 向 server 发起连接 server 接到请求,双方建立连接 client 向 server 发送消息 server 回应 client 一次读写完成,连接不关闭 后续读写操作… 长时间操作之后 client 发起关闭请求 优缺点分析 长连接可以省去较多的 TCP 建立和关闭的操作,节约时间。但是如果用户量太大容易造成服务器负载过高最终导致服务不可用 短连接对于服务器来说实现起来较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但是如果用户访问量很大, 往往可能在很短时间内需要创建大量的连接,造成服务器响应速度过慢 总结 小的 WEB 网站的 http 服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源来让套接字保持存活。 对于中大型 WEB 网站一般都采用长连接,好处是响应用户请求的时间更短,用户体验更好,虽然更耗硬件资源一些,但这都不是事儿。另外,数据库的连接用长连接,如果用短连接频繁的通信会造成 socket 错误。
2023年10月04日

浅析:XSS攻击、SQL注入攻击和CSRF攻击

SQL注入,旁注,XSS跨站,COOKIE欺骗,DDOS,0day 漏洞,社会工程学 等等等等,只要有数据交互,就会存在被入侵风险!哪怕你把网线拔掉,物理隔绝,我还可以利用传感器捕捉电磁辐射信号转换成模拟图像。你把门锁上,我就爬窗户;你把窗户关上,我就翻院墙;你把院墙加高,我就挖地洞。。。道高一尺魔高一丈,我始终坚信计算机不存在绝对的安全,你攻我防,此消彼长,有时候,魔与道只在一念之间。 下面,就让我们一起推开计算机中那另一扇不为人知的门 CSRF 基本概念 CSRF(Cross-site request forgery):跨站请求伪造。 攻击原理 用户是网站 A 的注册用户,且登录进去,于是网站 A 就给用户下发 cookie。 从上图可以看出,要完成一次 CSRF 攻击,受害者必须满足两个必要的条件: (1)登录受信任网站 A,并在本地生成 Cookie。(如果用户没有登录网站 A,那么网站 B 在诱导的时候,请求网站 A 的 api 接口时,会提示你登录) (2)在不登出 A 的情况下,访问危险网站 B(其实是利用了网站 A 的漏洞)。 我们在讲 CSRF 时,一定要把上面的两点说清楚。 温馨提示一下,cookie 保证了用户可以处于登录状态,但网站 B 其实拿不到 cookie。 防范措施 判断请求头中的 Referer 这个字段记录的是请求的来源。比如前端Vue页面 http://localhost:8080/#/showbooks上调用了服务端Django的接口 http://127.0.0.1:8000/books/?page=2&page_size=10, 那么在服务端,就可以通过 Referer 判断这个请求是来自哪里。 在实际应用中,这些跟业务逻辑无关的操作往往会放在拦截器中(或者说过滤器,不同技术使用的名词可能不同)。意思是说,在进入到业务逻辑之前,就应该要根据 Referer 的值来决定这个请求能不能处理。 用Flask 的话可以使用装饰器;在Django 中是叫中间件。每种技术它走的流程其实都一样。 而在 Django 可以通过以下代码获取对应信息 request.META['HTTP_REFERER'] # 来路 request.META.get("HTTP_USER_AGENT") # 请求头 在Flask中,则获取方式不同。 request.referrer # 来路 request.headers.get('User-Agent') # 请求头 但要注意的是,Referer 是浏览器设置的,在浏览器兼容性大不相同的时代中,如果存在某种浏览器允许用户修改这个值,那么 CSRF 漏洞依然存在。 在请求参数中加入 csrf token 讨论 GET 和 POST 两种请求,对于 GET,其实也没什么需要防范的。为什么? ...
2023年10月04日

大O标记法与常见时间复杂度

算法 : 内功心法, 是解决问题的一种思想 时间复杂度 $T(n)$ 由于每台机器的性能有所差别,所有其执行相同代码的时间也长短不一,故而推出一种计量方式,统计代码执行基本运算(函数调用需要看其源码的基本运算)的数量(n) 来确定一个算法的优劣,其中基本运算的循环按乘法计算,顺序结构按加法计算,分支结构取最大值。 for a in range(0, 1000): for b in range(0, 1000): for c in range(0, 1000): if a+b+c == 1000 and a**2 + b**2 + c**2: print('a,b,c,: {}, {}, {}'.format(a,b,c)) 上述代码的时间复杂度为 $T = 1000 * 1000 * 1000 * 2$ 那么如果将上述代码中的 1000 改为 2000, 则 $T = 2000 * 2000 * 2000 * 2$ 由于上述同样的代码由于不同的参数的 T 都不同,我们便将其统一成 N,这样上述代码的时间复杂度可以表示成: $T = N * N * N * 2$ 同样的我们抓住其主要 “矛盾” ,观其大,再将其简化成 $T= N^3$ 这样同一段代码的时间复杂度便不会根据其参数而发生改变了。 大 $O$ 标记法 $O()$ 其实和求极限的原理相似,抓住问题的主要矛盾,忽略那些细枝末节,也就像前面的 $T$的最后的样子。 时间复杂度的几条基本规则 基本步骤: 即只有常数项, 算作 $O(1)$ ...
2023年10月04日

哈希表

哈希表 哈希表是 key-value 类型的数据结构,通过关键码值直接进行访问。通过散列函数进行键和数组的下标映射从而决定该键值应该放在哪个位置,哈希表可以理解为一个键值需要按一定规则存放的数组 。 哈希函数 装填因子 冲突 起因 假设我们存在一个简单的键值对结构,键 - 员工号,值 - 是否在岗。现在需要这样一个功能,输入员工号,返回该员工是否在岗,理想的方法是创建一个长度为 Max(员工号) 的数组,数组下标就是员工号,数组中的值用 0 和 1 对是否在岗进行区分,这样只需要 O(1) 的时间复杂度就可以完成操作,但是扩展性不强,存在以下问题。 假设新进员工的员工号比 Max(员工号) 还要大,这就需要重新申请数组进行迁移操作。 假设一种极端的情况,存在两个员工,员工号分别是 1 和 100000000001,这样子的话按照先前的设计思路,是会浪费很大的存储空间的。 上面两点,第一点是因为数组的固定申请大小的属性所决定,而第二点就是引入哈希表的原因,会不会存在一个方法,让一个大员工号变小而而且没有标记,哈希函数便产生,假设此处的哈希规则是除 3 取模,则员工 1 得到的哈希值是 1,员工 100000000001 得到的哈希值是 2,这样的话按照设计思路,只需要一个大小为 2 的数组便可以覆盖了,这就是哈希思想。 算法中时间和空间是不能兼得的,哈希表就是一种用合理的时间消耗去减少大量空间消耗的操作,这取决于具体的功能要求。 哈希函数 上面的例子中哈希函数的设计很随意,但是从这个例子中我们也可以得到信息: 哈希函数就是一个映射,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表长允许的范围之内即可; 并不是所有的输入都只对应唯一一个输出,也就是哈希函数不可能做成一个一对一的映射关系,其本质是一个多对一的映射,这也就引出了下面一个概念–冲突。 冲突 只要不是一对一的映射关系,冲突就必然会发生,还是上面的极端例子,这时新加了一个员工号为 2 的员工,先不考虑我们的数组大小已经定为 2 了,按照之前的哈希函数,工号为 2 的员工哈希值也是 2,这与 100000000001 的员工一样了,这就是一个冲突,针对不同的解决思路,提出以下不同的解决方法。 开放地址 开放地址的意思是除了哈希函数得出的地址可用,当出现冲突的时候其他的地址也一样可用,常见的开放地址思想的方法有线性探测再散列,二次探测再散列,这些方法都是在第一选择被占用的情况下的解决方法。 再哈希法 这个方法是按顺序规定多个哈希函数,每次查询的时候按顺序调用哈希函数,调用到第一个为空的时候返回不存在,调用到此键的时候返回其值。 链地址法 将所有关键字哈希值相同的记录都存在同一线性链表中,这样不需要占用其他的哈希地址,相同的哈希值在一条链表上,按顺序遍历就可以找到。 公共溢出区 其基本思想是:所有关键字和基本表中关键字为相同哈希值的记录,不管他们由哈希函数得到的哈希地址是什么,一旦发生冲突,都填入溢出表。 装填因子α 一般情况下,处理冲突方法相同的哈希表,其平均查找长度依赖于哈希表的装填因子。哈希表的装填因子定义为表中填入的记录数和哈希表长度的壁纸,也就是标志着哈希表的装满程度。直观看来,α越小,发生冲突的可能性就越小,反之越大。一般 0.75 比较合适,涉及数学推导。
2023年10月04日

Cookie与Session的对比

Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。要跟踪该会话,必须引入一种状态保持机制。 状态保持 修改Http协议,使得它支持状态保持(难做到) Cookies:通过客户端来保持状态信息 Cookie是服务器发给客户端的特殊信息 Cookie是以文本的方式保存在客户端,每次请求时都带上它 Session:通过服务器端来保持状态信息 Session是服务器和客户端之间的一系列的交互动作 服务器为每个客户端开辟内存空间,从而保持状态信息 由于需要客户端也要持有一个标识(id),因此,也要求服务器端和客户端传输该标识, 标识(id)可以借助Cookie机制或者其他的途径来保存 COOKIE机制 Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。 Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie名称和值可以由服务器端开发自己定义,这样服务器可以知道该用户是否是合法用户以及是否需要重新登录等。服务器可以利用Cookies包含信息的任意性来筛选并经常性维护这些信息,以判断在HTTP传输中的状态。 Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息,如密码。 Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。 基本特点 Cookie以键值对Key-Value形势进行信息的存储,只能保存字符串对象,不能保存对象类型 Cookie基于域名安全,不同域名的Cookie是不能互相访问的 Cookie保存在客户端,需要客户端浏览器的支持,缺点:浏览器用户可能会禁用Cookie SESSION机制 如果说 Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。 每次客户端发送请求,服务端都检查是否含有sessionId。 如果有,则根据sessionId检索出session并处理;如果没有,则创建一个session,并绑定一个不重复的sessionId。 基本特点 状态信息保存在服务器端。这意味着安全性更高,可以存储敏感、重要的信息,支持更多字节,缺点:Session共享问题 通过类似与Hashtable的数据结构来保存,能支持任何类型的对象(session中可含有多个对象) 保存会话id的技术,依赖于 Cookie。默认情况下在客户端与服务器端之间通过cookie方式传递 SeesionId 总结 两种状态跟踪机制的比较 Cookie Session 存储位置 保持在客户端 保存在服务器端 存储类型 只能保持字符串对象 支持各种类型对象 实现机制 通过过期时间值区分Cookie的类型 ...
2023年10月04日

RESTful规范的API接口设计

在项目中,需要为 APP 撰写 API。刚开始接触的时候,并没有考虑太多,就想提供 URL,APP 端通过该 URL 进行查询、创建、更新等操作即可。但再对相关规范进行了解后,才发现,API 的设计并没有那么简单,远远不是 URL 的问题,而是一个通信协议的整体架构。 使用 SSL(https)来提供 URL 首先,使用 https 可以在数据包被抓取时多一层加密。 我们现在的 APP 使用环境大部分都是在路由器 WIFI 环境下,一旦路由器被入侵,那么黑客可以非常容易的抓取到用户通过路由器传输的数据,如果使用 http 未经加密,那么黑客可以很轻松的获取用户的信息,甚至是账户信息。 其次,即使使用 https,也要在 API 数据传输设计时,正确的采用加密。 例如直接将 token 信息放在 URL 中的做法,即使你使用了 https,黑客仅能抓到域名字符部分,不能抓到请求的数据,但是 URL 可以在浏览器或特殊客户端工具中直接看到。因此,使用 https 进行请求时,要采用 POST、PUT 或者 HEAD 的方式传输必要的数据。 使用 GET、POST、PUT、DELETE 这几种请求模式 请求模式也可以说是动作、数据传输方式,通常我们在 web 中的 form 有 GET、POST 两种。 而在 HTTP 中,存在以下这几种。 请求方式 功能 GET(选择) 从服务器上获取一个具体的资源或者一个资源列表。 POST(创建) 在服务器上创建一个新的资源。 PUT(更新) 以整体的方式更新服务器上的一个资源。 PATCH (更新) 只更新服务器上一个资源的一个属性。 DELETE(删除) <td ...
2023年10月04日

JWT浅析

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519). token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。 JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。 Jwt起源 说起 JWT,我们应该来谈一谈基于 token 的认证和传统的 session 认证的区别。 传统的 session 认证 我们知道,http 协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据 http 协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为 cookie, 以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了, 这就是传统的基于 session 认证。 但是这种基于 session 的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于 session 认证应用的问题就会暴露出来. 基于 session 认证所显露的问题 Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言 session 都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。 扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上, 这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。 CSRF: 因为是基于 cookie 来进行用户识别的, cookie 如果被截获,用户就会很容易受到跨站请求伪造的攻击。 基于 token 的鉴权机制 基于 token 的鉴权机制类似于 http 协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于 token 认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。 流程上是这样的: 用户使用用户名密码来请求服务器 服务器进行验证用户的信息 服务器通过验证发送给用户一个 token 客户端存储 token,并在每次请求时附送上这个 token 值 服务端验证 token 值,并返回数据 这个 token 必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *。 那么我们现在回到 JWT 的主题上。 JWT解析 网上大多数介绍JWT的文章实际介绍的都是JWS(JSON Web Signature),也往往导致了人们对于JWT的误解,但是JWT并不等于JWS,JWS只是JWT的一种实现,除了JWS外,JWE(JSON Web Encryption)也是JWT的一种实现。 下面就来详细介绍一下JWT与JWE的两种实现方式: ...
2023年10月04日

HTTP请求方法

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。 HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。 HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。 方法 描述 GET 请求指定的页面信息,并返回实体主体。 HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 PUT 从客户端向服务器传送的数据取代指定的文档的内容。 DELETE 请求服务器删除指定的页面。 CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 OPTIONS 允许客户端查看服务器的性能。 TRACE 回显服务器收到的请求,主要用于测试或诊断。 PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新 。
2023年10月04日

HTTP简介

网络基础 TCP/IP 为了理解 HTTP,我们有必要事先了解一下 TCP/IP 协议族。 通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作 的。而 HTTP 属于它内部的一个子集。 TCP/IP 协议族 TCP/IP 协议族是互联网相关的各类协议族的总称 像这样把与互联网相关联的协议集合起来总称为 TCP/IP。也有说法 认为,TCP/IP 是指 TCP 和 IP 这两种协议。还有一种说法认为,TCP/ IP 是在 IP 协议的通信过程中,使用到的协议族的统称。 TCP/IP 分层管理 TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分为以下 4 层: 应用层:决定向用户提供应用服务时通信的活动, FTP(File Transfer Protocol) 文件传输协议、DNS(Domain Name System) 域名系统、HTTP(HyperText Transfer Protocol) 传输层:提供处于网络连接中两台计算机之间的数据传输。 TCP(Transmission Control Protocol) 传输控制协议、UDP(User Data Protocol) 用户数据报协议 网络层(网络互联层):处理在网络上流动的数据包(数据包是网络传输的最小数据单位)。该层规定了通过怎样的路径(传输路线)到达对方计算机,并传递数据。作用就是在与对方计算机之间通过多台计算机或网络设备进行传输时,选择一条传输路线。 链路层(数据链路层、网络接口层):用来处理网络的硬件部分。包括控制操作系统、硬件设备驱动、NIC(Network Interface Card,网络适配器)、光纤等物理课件部分(连接器等一切传输媒介)。 TCP/IP 通信传输流 应用发请求通过 TCP 处理报文进行分隔发送给网络层网络层增加 MAC 地址给链路, 之后反向操作, 请求数据的时候每一层处理完成后会给这个数据加上这个层的首部信息, 相反, 处理请求的时候, 每处理一层就删除一个首部, 这叫做数据信息的封装 (encapsulate)。 与 HTTP 关系密切的协议 : IP、TCP 和DNS IP ...
2023年10月04日