1. Http
1.1 Http的定义
超文本传输协议(Hypertext Transfer Protocol,HTTP)是用于分布式、协作式和超媒体信息系统的应用层协议。它是互联网上最广泛应用的数据通信协议之一,尤其对于万维网(WWW)服务而言是至关重要的基础。HTTP协议定义了客户端(如网页浏览器)和服务器之间的通信格式和交互方式。
1.2 Http协议的特点
- 请求/响应模型
- HTTP采用客户端发起请求,服务器返回响应的模式进行工作。客户端通过发送一个HTTP请求来获取或提交网页资源,服务器根据请求内容生成相应的HTTP响应并回送给客户端。
- 无状态性
- HTTP协议本身是无状态的,这意味着每次请求都是独立处理,服务器不保留客户端请求之间的任何上下文信息。后来引入的Cookie和Session机制弥补了这一特性带来的问题,允许在多次请求间维持状态信息。
- 基于TCP/IP
- HTTP通常运行在TCP/IP协议栈的应用层之上,默认使用TCP端口80进行通信。HTTPS(安全HTTP)则使用SSL/TLS加密,在默认情况下运行在TCP端口443上。
- 消息结构
- HTTP消息包括请求消息和响应消息,它们由起始行、头部(headers)、空行和可选的消息主体组成。起始行定义了操作方法(GET、POST等)和目标资源的URI;头部包含了若干属性值对,描述了请求或响应的附加信息;消息主体承载了实际要传输的数据内容,如HTML文档、图片或其他类型的数据。
- 版本演化
- HTTP协议经历了多个版本的发展,例如HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3,每个新版本都在性能、效率、安全性等方面有所改进。
1.3 Http协议的缺点
- 明文运输
- 导致可能会被窃听
- 不验证报文的完整性
- 导致可能会被篡改
- 无法验证上方的身份
- 可能会出现伪装攻击
1.3.1 如何解决“明文传输”
可以使用对称加密,即加密和解密使用的是同一密钥S。但是如何把密钥交到对方手上就是一个很大的问题。
为了解决对称加密中的密钥分发难题,数学家们设计出了非对称加密体系。非对称加密算法的核心特点是采用一对密钥,一个是公开的公钥,另一个是私密的私钥。这两把密钥不是互相解密的关系,而是具有特定的匹配性:用公钥加密的数据只能通过对应的私钥解密,私钥加密的可以用公钥进行解密。
设想场景是这样的:假设A作为客户端,B作为服务端。首先,A和B各自生成一对非对称密钥,即公钥和私钥,并将各自的公钥安全地发布在网络上,使得任何人都能获取到A的公钥A_pub和B的公钥B_pub。
当A需要向B发送加密信息时,A会使用从网络上获取到的B的公钥B_pub来加密要发送的信息。这样一来,即便信息在互联网上传输的过程中被第三方截获,由于只有B持有的私钥B_priv能够解密这条信息,所以他人无法解读和篡改其中的内容。
最后,当B接收到经由其公钥加密的密文后,只需使用自己的私钥B_priv对其进行解密,从而确保了通信的保密性和完整性。通过这种方法,非对称加密算法有效地解决了在开放网络环境下安全传输密钥的问题,保障了数据在传输过程中的安全。
存在的问题
如果有一个中间人M在客户端和服务端获取对方公钥的时候,用自己的公钥M进行了替换。那么中间人不仅可以解析消息,还可以篡改消息。因为客户端A所认为的公钥B其实是公钥M,服务端认为的公钥A其实也是公钥M。这就涉及到了一个问题,如何验证接收到的公钥是你要的公钥。
1.3.2 利用数字证书
因为服务端的公钥无法在客户端证明确实是来自于服务端的,所以需要找一个第三方机构来做公证证明这个公钥确实是来自于服务端的。那怎么做公证呢?
服务端去证书授权中心申请证书,服务端会把自己的网站信息以及服务端公钥给到证书授权中心那边,而证书授权中心会根据这些生成一张由网站信息、证书信息、证书授权中心的数字签名以及服务端公钥等组成的证书。这里需要注意的是网站信息、证书信息、服务端公钥等信息在证书中都是以明文形式保存的。
新的问题来了:
- 如何保证这些明文没有被篡改过?
- 我们可以计算一个对应的消息摘要值,当明文被修改后,消息摘要值就对不上了
- 又有小朋友会问,那我如果修改明文后,重新计算了消息摘要值并替换呢?
- 那这个时候就需要对这个摘要利用CA的私钥进行数字签名(如果想要生成一个对应的数字签名就需要CA的私钥,很明显中间者无法获得)。
- 当客户端收到后就可以利用(消息摘要,数字签名,CA的公钥)进行验证
- 中间值修改消息后,即使生成新的消息摘要和数字签名也无法和CA的公钥进行匹配
- 新的问题又出现了,CA的公钥如何获得呢?
- CA机构的公钥是预装在操作系统中的,就这解决了公钥的来源问题。
代码如下:
# 导入rsa库
import rsa
# RSA密钥对生成
(public_key, private_key) = rsa.newkeys(2048) # 生成2048位密钥对
# RSA加密
message = b"This is a secret message"
cipher_text = rsa.encrypt(message, public_key)
# RSA解密
decrypted_message = rsa.decrypt(cipher_text, private_key)
# RSA数字签名
message_hash = rsa.compute_hash(message, 'SHA-256') # 计算消息摘要
signature = rsa.sign(message_hash, private_key, 'SHA-256')
# 验证签名
is_signature_valid = rsa.verify(message_hash, signature, public_key)
if is_signature_valid:
print("验证签名有效")
else:
print("中途被修改啦")
2.Https
HTTPS(全称为Hypertext Transfer Protocol Secure)是一种网络安全协议,设计用于在互联网上提供安全的通信和数据传输。它是在标准HTTP协议的基础上添加了一层安全措施,具体来说就是整合了SSL(Secure Sockets Layer)或其后续版本TLS(Transport Layer Security)协议,以实现数据加密、服务器身份验证以及消息完整性校验等功能。
当浏览器和服务器通过HTTPS连接时,它们会先执行握手过程来协商加密算法和交换公钥等信息,从而建立一个安全的连接通道。所有在HTTPS连接上传输的数据都会经过加密处理,这确保了敏感信息(如密码、信用卡号和个人信息)在网络中传输时不会被窃听或篡改。
此外,HTTPS还提供了服务器身份认证功能,通过证书颁发机构签发的SSL证书,客户端(如浏览器)可以验证服务器的真实身份,防止中间人攻击和仿冒网站。
总结来说,HTTPS的主要特点包括:
数据加密:使用对称加密和非对称加密相结合的方式来加密客户端和服务端之间的通信内容。
身份验证:服务器通过SSL/TLS证书向客户端证明其真实身份。
保证数据完整性:通过消息认证码(MAC)来防止数据在传输过程中被篡改。
默认使用端口号443而非HTTP的80端口。
2.1 为什么Https还有对称加密
因为非对称加密需要对信息进行加解密,这其中是非常耗时的,对称加密算法比非对称加密算法快大约1500倍!所以,HTTPS在通过非对称加密进行身份验证完毕后,后续通信会通过对称加密来进行,我们来看看是怎么实现的。
2.2 Https单向认证
- 客户端向服务端发送SSL协议版本号、加密算法种类、随机数等信息。
- 服务端给客户端返回服务端申请的证书(包含服务端公钥B、数字签名)、SSL协议版本号、加密算法种类、随机数等信息。
- 客户端拿到服务端返回的证书验证服务端的合法性,包括:
- 证书是否过期
- 该CA机构是否可靠
- 返回的公钥是否能正确解开返回证书中的数字签名
- 服务器证书上的域名是否和服务器的实际域名相匹配
验证通过后,将继续进行通信,否则,终止通信
- 客户端向服务端发送自己所能支持的对称加密方案,供服务端进行选择。
- 服务端在客户端提供的加密方案中选择加密程度最高的加密方式。
- 服务端将选择好的加密方案通过明文方式返回给客户端。
- 客户端接收到服务端返回的加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密密钥,使用服务端返回的公钥B进行加密,将加密后的随机码发送至服务端。
- 服务端收到客户端返回的加密信息后,使用自己的私钥B进行解密,获取对称加密密钥。 在接下来的会话中,服务端和客户端将会使用该对称加密密钥进行对称加密,保证通信过程中信息的安全。
2.3 Https双向认证
- 客户端向服务端发送SSL协议版本号、加密算法种类、随机数等信息。
- 服务端给客户端返回服务端申请的证书(包含服务端公钥B、数字签名)、SSL协议版本号、加密算法种类、随机数等信息。
- 客户端拿到服务端返回的证书验证服务端的合法性,包括:
- 证书是否过期
- 该CA机构是否可靠
- 返回的公钥是否能正确解开返回证书中的数字签名
- 服务器证书上的域名是否和服务器的实际域名相匹配
验证通过后,将继续进行通信,否则,终止通信
- 服务端要求客户端发送客户端的证书,客户端会将自己的证书发送至服务端。
- 服务端验证客户端的证书,通过验证后,获得客户端公钥A。
- 客户端向服务端发送自己所能支持的对称加密方案,供服务端进行选择。
- 服务端在客户端提供的加密方案中选择加密程度最高的加密方式。
- 服务端将选择好的加密方案通过客户端公钥A加密后返回给客户端。
- 客户端接收到服务端返回的信息后,通过客户端私钥A解密,获取到对称加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密密钥,使用服务端返回的公钥B进行加密,将加密后的随机码发送至服务端。
- 服务端收到客户端返回的加密信息后,使用自己的私钥B进行解密,获取对称加密密钥。 在接下来的会话中,服务端和客户端将会使用该对称加密密钥进行对称加密,保证通信过程中信息的安全。
使用单向认证还是双向认证是由服务端来决定的(默认单向)
3.Http各个版本
3.1 Http/0.9
HTTP/0.9 是超文本传输协议(Hypertext Transfer Protocol,HTTP)的第一个正式版本。这个早期版本于1991年随着万维网(World Wide Web)的诞生而出现,由蒂姆·伯纳斯-李(Tim Berners-Lee)设计。
特点:
- 请求方式简单
- 只支持GET请求方法。请求行中只包含要获取的资源文件名,不包含版本号、主机名或任何其他HTTP头信息。
- 响应格式简单
- 服务器回应的内容直接跟在换行符后面,没有状态行、响应头或者空行,只有纯文本或HTML内容
- 无错误代码反馈
- 如果请求失败,服务器无法通过HTTP协议返回特定的错误代码,只能关闭连接
- 不支持持久连接
- 每个请求与响应都对应一个新的TCP连接,连接在每次传输完成后立即关闭
3.2 Http/1.0
HTTP/1.0 是超文本传输协议(Hypertext Transfer Protocol,HTTP)的第二个正式版本,发布于1996年,是对早期HTTP/0.9的重大改进。相比于HTTP/0.9,HTTP/1.0引入了许多关键特性和增强功能,使其更适合大规模的Web服务:
特点
- 请求方法多样化
- 除了基本的GET方法之外,新增了POST方法,允许客户端向服务器发送数据。
- 状态码系统
- 在HTTP响应中加入了状态码,比如常见的200(成功)、404(未找到)、500(服务器内部错误)等
- 头部信息
- HTTP/1.0支持在请求和响应中携带头部信息,比如User-Agent、Content-Type、Connection等
- 持续连接选项
- 尽管默认情况下HTTP/1.0仍采用“每个请求-响应后关闭连接”的模式,但该版本首次引入了Connection: keep-alive头部字段,允许客户端和服务器协商保持TCP连接打开,以便复用连接处理多个请求,从而提高性能。
- 多部分数据
- HTTP/1.0支持多部分编码(multipart encoding),允许在一个HTTP消息体中发送多个不同类型的实体,这一特性在文件上传等场景下尤为重要
3.3 Http/1.1
HTTP/1.1 是超文本传输协议(Hypertext Transfer Protocol,HTTP)的第三个主要版本,发布于1999年,相较于HTTP/1.0做出了许多重要的改进和优化,旨在提高网络应用的性能和功能性。
特点
- 持久连接(Persistent Connections)
- HTTP/1.1默认启用持久连接,即TCP连接在处理完一个请求之后并不会立即关闭,而是保持一段时间内的开放状态,以便处理更多的请求,大大减少了建立连接的开销,提升了整体性能。
- 管道化(Pipelining)
- 在同一TCP连接上,客户端可以连续发送多个请求而不需等待前一个请求的响应,服务器则按照请求到达的顺序依次响应。虽然管道化理论上可以进一步提升性能,但由于队头阻塞(Head of Line Blocking)的问题,在实际应用中效果有限。
- 缓存控制(Cache Control)
- HTTP/1.1增强了缓存机制,引入了新的头部字段如Cache-Control、Expires、ETag等,使缓存管理更加灵活和精细。
- 分块传输编码(Chunked Transfer Encoding)
- 允许动态生成内容的长度未知时,服务器将响应内容分成若干个块进行传输,每一块都有自己的大小标识,这样客户端可以在接收到部分数据后就开始处理,无需预先知道整个响应的大小。
- Host头域
- 强制要求客户端在请求中指定Host头域,使得一台服务器可以托管多个域名和站点,为虚拟主机技术提供了基础。(简单来说就上在一个ip:port上可以部署多个网站,使用Host头域进行区分)
- 请求方法扩展
- HTTP/1.1定义了更多的请求方法,如PUT、DELETE、OPTIONS、HEAD等,增加了HTTP协议的交互能力。
- 错误通知更完善
- HTTP/1.1提供了更为丰富的状态码和错误信息,帮助开发者更好地理解和调试应用程序。
- 带宽优化
- 通过gzip压缩等方式,HTTP/1.1支持内容压缩传输,降低网络带宽消耗。
3.4 Http/2.0
HTTP/2.0 是 HTTP 协议的继 HTTP/1.1 后的重要升级版本,于2015年5月正式发布。HTTP/2.0 的核心目标是改善网页性能,特别是在高并发场景下减少延迟,提高网络资源利用率。主要的新特性包括:
特点
- 多路复用(Multiplexing)
- 这是HTTP/2最显著的改进之一。在HTTP/1.x中,一次TCP连接在同一时刻只能处理一个请求,而在HTTP/2中,一个TCP连接上可以并发处理多个请求和响应,消除了HTTP/1.x中的“队头阻塞”问题,大幅提高了页面加载速度。
- 二进制分帧(Binary Framing)
- HTTP/2将所有传输的信息分割成多个帧,这些帧可以交错、乱序发送,然后在另一端再重新组装。每个帧都有专门的目的,如HEADERS帧用于传输HTTP首部,DATA帧用于传输请求/响应主体。
- 头部压缩(Header Compression)
- HTTP/2使用HPACK算法对请求和响应的头部信息进行压缩,因为HTTP头部信息往往有很多重复内容,压缩头部信息可以显著减少数据传输量。
- 服务器推送(Server Push)
- 服务器在客户端请求一个资源的同时,可以预测客户端可能还需要哪些资源,并主动把这些资源推送给客户端,减少了客户端发起请求的延迟和往返时间。
- 优先级和流控制
- HTTP/2允许为每个流设置优先级,以便服务器合理安排资源发送顺序。另外,通过流控制机制,两端可以协调数据发送速度,防止拥塞和数据丢失。
- 单一连接
- 鼓励客户端和服务器维持一个长连接以供多个请求/响应交换,减少建立新连接的开销
重要概念
HTTP2.0中,有两个概念非常重要:帧(frame)和流(stream)。
帧是最小的数据单位,每个帧会标识出该帧属于哪个流,流是多个帧组成的数据流。
所谓多路复用,即在一个TCP连接中存在多个流,即可以同时发送多个请求,对端可以通过帧中的表示知道该帧属于哪个请求。在客户端,这些帧乱序发送,到对端后再根据每个帧首部的流标识符重新组装。通过该技术,可以避免HTTP旧版本的队头阻塞问题,极大提高传输性能。
3.5 Http/3.0
HTTP/3.0 是超文本传输协议(HTTP)的最新版本,旨在进一步改进网络应用的性能和效率。作为HTTP/2.0的继承者,HTTP/3.0 最显著的变化是放弃了对TCP的依赖,转而采用基于UDP的QUIC协议作为传输层。
QUIC(Quick UDP Internet Connections)最初由Google提出并开发,现在已经成为IETF标准。QUIC的设计目标在于解决TCP存在的延迟和性能问题,特别是队头阻塞(Head-of-line blocking)问题,同时提供类似TCP的可靠传输保证,包括流量控制、错误检测和纠正、连接迁移等功能。
特点
- 多路复用和低延迟
- 每个HTTP请求/响应在QUIC协议中映射为一个独立的数据流,即使网络中某数据包丢失,也不会阻塞其它数据流,从而减少了延迟。
- 快速连接建立
- QUIC使用了基于TLS 1.3的快速握手机制,可以实现0-RTT(Zero Round Trip Time)的连接建立,也就是说在某些情况下客户端可以在第一个数据包就发送请求数据,而无需等待握手完成。
- 连接迁移
- QUIC支持在IP地址改变(如Wi-Fi切换到蜂窝网络)时保持连接,这有助于移动设备在网络条件改变时保持活跃连接和流畅体验。
- 安全集成
- QUIC内建了TLS加密,确保数据在传输过程中受到保护,同时也简化了安全传输的实现。
- 错误恢复和重传机制
- QUIC拥有更好的丢包检测和重传策略,可以更快速地识别和补偿丢包,从而提高传输效率。