简介:
libcurl是一个开源的、跨平台的网络传输库,它支持多种协议,包括HTTP、HTTPS、FTP、FTPS、TFTP、SCP、SFTP、SMB、SMBS、TELNET、DICT、LDAP、LDAPS、FILE、POP3、IMAP、SMTP、RTMP和RTMPS。libcurl库以其灵活性和易用性而闻名,它允许开发者轻松地在其应用程序中集成网络通信功能,本章我们先对HTTP和HTTPS,密码学等基础知识进行一个学习和掌握
一、HTTP相关知识
1.1 http协议的特性
HTTP(超文本传输协议)是一种建立在TCP/IP协议栈之上的应用层协议。它通常使用TCP作为其传输层协议,并且默认情况下使用端口80进行通信。在某些情况下,HTTP服务也可能使用端口8080,尤其是在端口80被其他服务占用时。
HTTP协议的两个关键特性是:
- 无状态:这意味着HTTP服务器不会在不同的请求之间保留任何客户端状态信息。每个HTTP请求都是独立的,服务器不会记住之前的请求。这种设计简化了服务器端的实现,因为它不需要维护客户端状态。然而,这也意味着如果需要维护状态(例如,在用户会话中),则需要使用其他机制,如cookies或会话标识符。
- 无连接:传统的HTTP(HTTP/1.0)在处理完一个请求后会立即关闭TCP连接。这意味着每个请求都需要重新建立连接,这有助于减少服务器的资源占用,但同时也可能导致效率降低。HTTP/1.1引入了持久连接(keep-alive)机制,允许在单个TCP连接上发送多个请求和接收响应,从而提高了效率。
这些特性使得HTTP协议简单且易于实现,但同时也带来了一些性能和状态管理方面的挑战。随着HTTP/1.1、HTTP/2和HTTP/3的引入,HTTP协议在这些方面得到了改进,例如通过持久连接和多路复用来减少延迟,以及通过加密提高安全性。
1.2 http协议的请求与响应:
HTTP协议的报文可以通过抓包工具如HTTPWatch来捕获和分析。HTTP报文分为请求报文和响应报文,它们都遵循相似的结构,主要由以下三部分组成:
1. 请求行(Request Line)或状态行(Status Line):
(1)在请求报文中,请求行包含了请求方法(如GET、POST、PUT等)、请求的URL和HTTP协议的版本。
(2)在响应报文中,状态行包含了HTTP协议的版本、状态码(如200、404等)和状态描述。
2. 请求头(Headers)或响应头(Headers):
请求头和响应头包含了关于请求或响应的额外信息,如内容类型(Content-Type)、内容长度(Content-Length)、缓存控制(Cache-Control)、cookie、认证信息等。这些头部字段都是以键值对的形式出现,并且每行一个。
3. 请求体(Body)或响应体(Body):
请求体通常在POST或PUT请求中使用,用于发送数据到服务器,如表单数据或JSON数据。 响应体包含了服务器返回的实际数据,如HTML文档、图片、视频等。
HTTP报文在传输时是使用ASCII码格式,这使得它们易于阅读和调试。然而,实际的数据(如图片、视频、二进制文件等)通常会被编码为字节流,并通过Content-Type头部字段指定其类型。
在TCP/IP协议栈中,HTTP协议工作在应用层,而TCP则作为传输层协议负责提供可靠的数据传输服务。当HTTP报文准备好后,它们会被封装在TCP段中,并通过IP层进行传输。
1.2.1 请求行:
1. GET:
(1)GET方法用于请求指定的资源。它是HTTP中最常用的方法之一,通常用于获取数据。
(2)GET请求的参数是通过URL的查询字符串(query string)传递的,这意味着参数是可见的,并且可以被浏览器缓存。
(3)由于参数暴露在URL中,GET请求不适合传输敏感信息(如密码)。
(4)GET请求是幂等的,即多次相同的GET请求应该产生相同的资源状态,不会对服务器上的资源产生副作用。
2. POST:
(1)POST方法用于向指定资源提交数据,请求服务器进行处理(例如提交表单或上传文件)。
(2)POST请求的数据包含在请求体中,而不是URL中,这使得它可以传输更大量的数据,并且相对安全(尽管仍然不是加密的)。
(3)POST请求不是幂等的,即多次相同的POST请求可能会产生不同的结果,因为每次请求都可能创建新的资源。
3. PUT:
(1)PUT方法用于向指定资源位置上传最新的内容。
(2)PUT请求通常用于更新现有资源,它要求客户端提供完整的资源表示,而不仅仅是更改的部分。
(3)PUT请求是幂等的,无论执行多少次,只要资源标识符(通常是URL)相同,结果都应该是一样的。这意味着如果一个PUT请求成功执行,后续相同的PUT请求不应该改变服务器上的资源状态。
4. URL:
URL(统一资源定位符)是网络资源的地址。在HTTP请求中,URL指定了客户端希望访问的服务器上的资源位置。
URL通常包括协议(如http或https)、服务器地址(域名或IP地址)、端口号(可选)、路径和查询字符串(可选)。
例如,https://www.example.com/path/to/resource?param1=value1¶m2=value2 中:
https 是协议
www.example.com 是服务器地址
/path/to/resource 是路径
?param1=value1¶m2=value2 是查询字符串。
1.2.2 GET和POST区别:
GET和POST请求在多个方面有所不同,这些差异主要体现在URL可见性、数据传输方式、缓存性和对后续页面的影响等方面:
1. URL可见性:
(1)GET:参数直接附加在URL的查询字符串中,因此对用户和任何监视网络流量的人来说都是可见的。
(2)POST:参数包含在请求体(body)中,而不是URL中,因此不会显示在浏览器的地址栏或服务器日志中,提供了一定程度的隐私性。
2. 数据传输:
(1)GET:数据是通过URL的查询字符串传递的,格式通常为`key1=value1&key2=value2`。
(2)POST:数据是通过请求体传输的,可以采用多种格式,如`application/x-www-form-urlencoded`、`multipart/form-data`或`application/json`等。
3. 缓存性:
(1)GET:由于GET请求通常用于获取数据,它们可以被浏览器和服务器缓存,以提高性能。例如,浏览器可能会缓存GET请求的响应,以便在用户再次访问相同页面时快速加载。
(2)POST:POST请求通常用于修改服务器上的数据,因此它们不应该被缓存,以避免潜在的数据不一致问题。
4. 对后续页面的影响:
(1)GET:GET请求不应该对服务器上的数据产生副作用,即它们应该是幂等的。这意味着无论执行多少次相同的GET请求,服务器上的数据状态应该保持不变。
(2)POST:POST请求可能会改变服务器上的数据状态,例如创建新资源或更新现有资源。因此,它们不是幂等的,多次执行相同的POST请求可能会产生不同的结果。
5. 传输数据的大小:
(1) GET:由于GET请求的数据是通过URL传递的,而URL的长度通常有限制(不同的浏览器和服务器可能有不同的限制,但一般在2KB到4KB之间),因此GET请求能够传输的数据量相对较小。
(2)POST:POST请求的数据是通过请求体传输的,理论上可以传输大量数据,只要服务器和客户端的配置允许。在PHP中,可以通过修改`php.ini`文件中的`post_max_size`设置来调整POST请求的最大数据量。
6. 安全性:
(1)GET:由于GET请求的参数直接显示在URL中,容易被第三方截获和查看,因此不适合传输敏感信息。
(2)POST:POST请求的参数包含在请求体中,不会直接显示在URL或服务器日志中,因此提供了一定程度的安全性。然而,这并不意味着POST请求就是完全安全的,因为数据在传输过程中仍然可能被截获。为了提高安全性,通常需要对传输的数据进行加密处理。
本质区别:
TCP数据包的数量:有一种观点认为,GET请求只产生一个TCP数据包(请求头和数据一起发送),而POST请求产生两个TCP数据包(先发送请求头,服务器响应后,再发送数据)。然而,这种说法并不准确。实际上,GET和POST请求的数据包数量取决于具体的实现和网络环境。在某些情况下,POST请求也可能只发送一个数据包,特别是当数据量较小的时候。
1.2.3 请求头
在网络通信中,浏览器向服务器发送数据通常是通过HTTP请求完成的。这些数据可以包含各种状态信息和标识数据。如果你想要以特定的格式发送这些信息,例如每条信息一行,包含信息名和信息值,你可以使用HTTP请求的POST方法,并在请求体中以键值对的形式发送这些数据。
注意:请求头的信息,需要使用一个空行结束!
1.2.4 请求体
请求代理端项服务器端,发送的请求数据!
典型的就是POST形式发送的表单数据!
get请求,没有请求主体部分! get数据是在请求行中的url上进行传递的!
示例HTTP请求的格式:
GET /index.html HTTP/1.1\r\n Host: www.example.com\r\n User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36\r\n Accept: text/html,application/xhtml+xml\r\n \r\n
- 请求行:包含了请求方法(GET)、请求的资源路径(/index.html)和HTTP协议的版本(HTTP/1.1)。
- 请求头:包含了一系列的键值对,每个键值对由冒号分隔,例如Host: www.example.com。请求头提供了关于请求的额外信息,例如Host字段指定了请求的目标主机。
- 空行:由一个\r\n组成的空行标志着请求头的结束。
1.2.5 响应行
响应行包括协议版本、状态码和状态消息。
1. 协议版本:指明服务器所使用的HTTP协议版本。常见的版本有HTTP/1.0和HTTP/1.1。例如,HTTP/1.1。
2. 状态码:用于表示服务器对请求的处理结果的数字代码。状态码由三位数字组成,每个状态码都有特定的含义。常见的状态码有200、404、500等。例如,200表示成功,404表示未找到请求的资源。
3. 状态消息:是与状态码对应的简短文本描述,提供对状态码更详细的说明。状态消息不是必需的,但在调试和查看响应时很有用。例如,对于状态码200,状态消息可能是"OK";对于状态码404,状态消息可能是"Not Found"。
响应行的示例:HTTP/1.1 200 OK
其中,HTTP/1.1是协议版本,200是状态码,OK是状态消息。
通过解析响应行的协议版本、状态码和状态消息,客户端可以了解服务器对请求的处理结果,并根据需要进行后续操作。
典型;
500服务器内部错误
404请求的页面没有找到
403没有权限
200请求成功
1.2.5 响应头
1. Content-Type(内容类型):该字段指示了响应主体数据的媒体类型。具体的值可以是text/html、application/json、image/jpeg等。例如,Content-Type: text/html表示响应主体的数据格式为HTML文本。
2. Content-Length(内容长度):该字段指示了响应主体数据的字节长度。这个信息对于客户端来说是很重要的,因为它可以帮助客户端正确处理响应的数据。例如,Content-Length: 1024表示响应主体数据的长度为1024字节。
3. Date(日期):该字段指示了响应生成的日期和时间,使用格林尼治标准时间(GMT)格式。这个信息对于记录和调试响应很有用。例如,Date: Sun, 28 Nov 2021 12:00:00 GMT表示响应生成的时间为2021年11月28日12点。
这些响应头字段在HTTP响应中提供了额外的元数据信息,使客户端能够更好地理解和处理服务器返回的数据。客户端可以根据Content-Type字段确定如何解析和显示响应主体数据,根据Content-Length字段确定正确的读取长度,根据Date字段了解服务器响应的时间。
1.2.6 响应体
每个响应行和响应头都以\r\n结尾。注意,响应头之后的空行(\r\n)标志着响应头的结束,之后的内容即为响应主体。
在浏览器的主体区域显示的数据就是响应主体的内容,它可以根据Content-Type字段的值进行解析和显示。在示例中,响应主体包含了一个简单的HTML页面,浏览器可以解析并渲染该页面。
以下是一个示例HTTP响应的格式:
HTTP/1.1 200 OK\r\n Date: Sun, 28 Nov 2021 12:00:00 GMT\r\n Content-Type: text/html\r\n Content-Length: 1024\r\n \r\n <!DOCTYPE html>\r\n <html>\r\n <head>\r\n <title>Example</title>\r\n </head>\r\n <body>\r\n <h1>Hello, World!</h1>\r\n </body>\r\n </html>\r\n
- 状态行:包含了HTTP协议的版本(HTTP/1.1),状态码(200)和状态描述(OK)。
- 响应头:类似于请求头,包含了一系列的键值对,每个键值对由冒号分隔。示例中的响应头包含了Date、Content-Type和Content-Length等字段,用于提供关于响应的额外信息。
- 空行:由一个\r\n组成的空行标志着响应头的结束。
- 响应主体:在空行之后的内容即为响应主体,其中包含了HTML文档的内容。
二、HTTPS协议
2.1 简介:
HTTP协议通过明文传输数据,这意味着数据在客户端和服务器之间传输时没有加密。任何在传输路径上的中间人都可以轻松截取和读取这些数据,由于数据未加密,使用HTTP协议进行敏感信息的传输容易导致数据泄露和安全风险,如密码、信用卡信息等。
HTTPS在HTTP和TCP之间添加了一层SSL/TLS(Secure Sockets Layer/Transport Layer Security),实现了身份验证和数据加密,SSL/TLS使用数字证书对服务器进行身份验证,确保客户端连接到的是真正的服务器,而不是冒充的中间人,HTTPS通过加密通信通道,显著提高了数据传输的安全性,适用于需要保护敏感信息的应用场景,如银行交易、在线购物、社交媒体等。
2.2 原理:
- HTTP的工作原理:
- 客户端(如浏览器)向服务器发送HTTP请求。
- 服务器处理请求并返回HTTP响应。
- 数据在传输过程中不加密,可以被任何中间人读取。
- HTTPS的工作原理:
- 客户端向服务器发送HTTPS请求。
- 服务器返回其SSL/TLS证书,证书中包含服务器的公钥。
- 客户端验证服务器证书的有效性(通常通过信任的证书颁发机构进行验证)。
- 客户端生成一个对称加密密钥,并使用服务器的公钥对其加密后发送给服务器。
- 服务器使用其私钥解密该对称密钥。
- 之后,客户端和服务器使用对称加密密钥进行加密通信,确保数据安全。
2.3 使用情景
1. HTTP的使用场景:
适用于不涉及敏感信息的普通网页浏览,如博客、新闻网站等。
2. HTTPS的使用场景:
适用于需要保护用户隐私和敏感数据的应用场景,如电子商务网站、银行和金融服务、社交媒体平台等。
2.4 优缺点
- HTTP优点:
- 速度较快,因为数据不需要加密和解密。
- 实现简单,适用于非敏感数据的传输。
- HTTP缺点:
- 安全性低,容易被攻击和窃取数据。
- HTTPS优点:
- 提供数据加密和服务器身份验证,确保通信安全。
- 保护用户隐私,防止数据泄露。
- 增强用户信任,有助于提升网站信誉和SEO排名。
- HTTPS缺点:
- 加密和解密过程增加了数据传输的开销,可能会影响性能。
- 证书管理需要额外成本和复杂度。
三、密码学基础
3.1 基本概念
1. 明文 (Plaintext):
指未经过加密处理的原始数据,能够被直接读取和理解。
2. 密文 (Ciphertext):
明文通过加密算法处理后的数据,密文是难以理解的,只有被授权的接收者才能解密并恢复成明文。
3. 密钥 (Key):
用于加密和解密数据的参数。密钥的安全性直接影响数据的安全性。
3.2 密钥类型
1. 对称密钥(Symmetric Key):
同一密钥用于加密和解密过程。对称密钥加密的特点是速度快,适用于大数据量的加密,但密钥需要安全地共享给双方。
常见算法:DES、3DES、AES、Blowfish、RC5、IDEA。
2. 非对称密钥(Asymmetric Key):
使用一对密钥,即公钥和私钥。公钥用于加密,私钥用于解密。私钥保持秘密,公钥可以公开。
常见算法:RSA、DSA、ECC。
3.3 对称加密
对称加密(Symmetric Encryption):
特点:加密和解密使用相同的密钥,加密过程和算法公开,速度快,适合大数据量加密。
安全性:密钥的安全分发和保护是对称加密的关键,因为一旦密钥泄露,数据的安全性将受到威胁。
加密过程:
明文 + 加密算法 + 密钥 => 密文
解密过程:
密文 + 解密算法 + 密钥 => 明文
3.4 非对称加密
非对称加密(Asymmetric Encryption):
特点:加密和解密使用不同的密钥对,公钥加密,私钥解密。由于算法复杂,非对称加密速度较慢,通常用于小数据量的加密或密钥交换。
安全性:即使公钥公开,私钥未泄露的情况下,数据仍然是安全的。
加密过程:
明文 + 加密算法 + 公钥 => 密文
解密过程:
密文 + 解密算法 + 私钥 => 明文
3.5 对称加密示例算法
1. DES(Data Encryption Standard):
使用56位密钥,对数据进行64位分组加密。
现已逐渐被认为不够安全,主要用于历史兼容性。
2. 3DES(Triple DES):
通过三次重复应用DES算法,增加安全性。
使用两个或三个不同的56位密钥,密钥长度可达112或168位。
3. AES(Advanced Encryption Standard):
采用128位、192位或256位密钥,对数据进行128位分组加密。
广泛应用于各种场景,具有较高的安全性和性能。
3.6 非对称加密示例算法
1. RSA(Rivest-Shamir-Adleman):
基于大素数因子分解问题的难度。
常用于数字签名和密钥交换,密钥长度通常为1024位、2048位或更长。
2. ECC(Elliptic Curve Cryptography):
基于椭圆曲线数学问题,提供相同安全性的情况下,密钥长度较短,性能更高。
常用于资源受限的环境,如移动设备和智能卡。
3.7 示例应用场景
对称加密:用于实际数据的加密传输,如文件加密、磁盘加密。
非对称加密:用于安全密钥交换和数字签名,如HTTPS协议中的SSL/TLS握手过程。
通过结合对称加密和非对称加密的优势,可以实现高效且安全的数据保护。例如,常见的做法是使用非对称加密来安全地交换对称密钥,然后使用对称密钥进行大数据量的加密传输。这种方式兼顾了安全性和性能,是许多现代加密系统的基础。