🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# HTTP协议和HTTPS协议 Http协议是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。 请求报文格式: ~~~java 请求方法 URL 版本 \n 多个首部字段名:值 \n \n 实体主体 ~~~ 主要包括:请求行、首部行、请求体。 请求方法有如下几种方式: - Option:请求一些选项的信息。 - get:请求读取由URL所标志的信息。 - post:给服务器添加资源。 - head:请求读取由URL所标志的信息的首部。 - put:修改服务器资源。 - delete:删除指明的URL所标志的资源。 - trace:用来进行本地环回测试的请求报文。 - connect:用于代理服务器。 版本指的是HTTP的版本,现在一般都指http1.1。 响应报文格式: ~~~java 版本 状态码 状态描述 \n 多个首部字段:值 \n \n 实体主体 ~~~ 包括:状态行、首部行、响应体 状态码分类: - 1xx通知信息,请求收到了或正在处理。 - 2xx请求成功,常见有200,202,206。 - 3xx重定向。 - 4xx客户端错误,常见有400,403,404。 - 5xx服务器错误,常见有500,506。 **首部行中常见字段:** 1. Host字段 用于客户端发送请求时,指定服务器的域名。 2. Content-Length字段 服务器返回时用于表明本次响应的数据长度。 3. Connection 用于表示是否是持久化的连接,以便其他请求复用这条连接 ~~~java Connection:Keep-Alive ~~~ HTTP/1.1 版本的默认连接都是持久连接,但为了兼容⽼版本的 HTTP,需要指定 Connection ⾸部字段的值为Keep-Alive 。 4. Content-Type 请求报文中表示发送的参数的数据类型,响应报文中表示响应实体数据的数据类型。 5. Accept:\*/\* 客户端声明自己可以接受任何格式的数据。   ## HTTPS协议 HTTP协议是明文传输的协议,带来了如下几个风险: 1. 窃听风险:第三方可以获知通信内容。 2. 篡改风险:第三方可以修改通信内容。 3. 冒充风险:第三方可以冒充他人身份参与通信。 由此引入了HTTPS协议:HTTPS = SSL/TLS + HTTP。 * 安全套接字层SSL (Secure Socket Layer) * 运输层安全TLS(Transport Layer Security)。 :-: ![](https://img.kancloud.cn/81/d6/81d662215ce1917ebe2d113c7beee6c6_1200x494.png) > 关于信息加密的解决方案: > 1. 最开始采用公钥加密的方式(对称加密),客户端和服务器持有相同的一份密钥,信息根据这份密钥加密后再根据这份密钥解密;常用的算法有:DES、AES等。但是这种做法密钥传输过程中很容易被捕获,不安全。 > 2. 之后引入了非对称加密的方式,密钥分为公钥和私钥,公钥是公开的,私钥是服务器私有的;信息通过公钥加密之后只能通过私钥解密,通过私钥加密后只能通过公钥解密。这种方式可以保证在加密解密的过程中是安全的,只用一对公私钥可以保证客户端向服务器发送的消息是可以正确被解密的,但是服务器向客户端发送公钥的时候容易被人截获之后篡改公钥信息,即中间人攻击。才用两对公私钥可以保证通信的正确性,但是非对称加密的方式是非常耗费算力资源的。 > 3. 对称和非对称混合加密:SSL/TLS的使用方式。 SSL/TLS采用了公钥和私钥混合加密的方式,其总体的思路如下: 1. 服务器往客户端发送非对称加密中的公钥。 2. 客户端拿到公钥之后随机生成一份**密钥**,并用公钥进行加密后发送给服务器。 3. 服务器拿到**密钥**后用私钥进行解密。 4. 之后客户端和服务器双方都通过这份**密钥**进行对称加密和解密。 这个过程只用到了一次非对称加密和解密,这也是SSL/TLS握手过程发生的,其他正式通信都用对称加密的方式。 两个问题: 1. 如何保证公钥不会被篡改? > 将公钥放在数字证书中,证书可信,公钥就可信,就像身份证一样。 2. 如何保证证书可信? > 把证书生成一份签名,对比证书和签名就能发现证书是否被篡改。 :-: ![](https://pic2.zhimg.com/v2-7c78935389af46e197e96d9cd91c06dd_b.jpg)   ### SSL/TLS握手过程 其过程如下: (1) 客户端向服务器端索要并验证公钥。 (2) 双方协商生成"对话密钥"。 (3) 双方采用"对话密钥"进行加密通信。 前两步称为握手阶段,该阶段涉及四次通信,通信过程都是明文的,具体过程如下: 1. 客户端发送请求(ClientHello) 发送的信息如下: ~~~java (1) 支持的协议版本,比如TLS 1.0版。 (2) 一个客户端生成的随机数,稍后用于生成"对话密钥"。 (3) 支持的加密方法,比如RSA公钥加密。 (4) 支持的压缩方法。 ~~~ 2. 服务器回应(ServerHello) 服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。包含如下信息: ~~~java (1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。 (2) 一个服务器生成的随机数,稍后用于生成"对话密钥"。 (3) 确认使用的加密方法,比如RSA公钥加密。 (4) 服务器证书。 ~~~ 3. 客户端回应 验证服务端发送的信息并向访问者发出提示信息,如果证书没有问题会向服务器发送如下的信息: ~~~java (1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。 (2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。 (3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前 面发送的所有内容的hash值,用来供服务器校验。 ~~~ 总共生成了三个随机数用于生成“对话密钥”。 4. 服务器最后回应 服务器收到客户端生成的三个随机数后,会计算生成本次回话所用的“会话密钥”,然后向客户端发送最后如下的消息: ~~~java (1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。 (2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是 前面发送的所有内容的hash值,用来供客户端校验。 ~~~ 至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。 【参考】 1. https://www.zhihu.com/search?type=content&q=https