编写本文的目的是让新手们快速了解HTTP协议相关知识,文中列举的信息如果有误,希望你能指出。期待大家共同进步。
HTTP是建立在TCP协议之上的请求响应协议,由于安全性需求衍生出HTTPS网络协议,因此HTTPS处于HTTP和TCP协议中间,建立起安全可靠的HTTP通道。
HTTPS的安全性是依赖于SSL协议,在客户端和服务器通讯前,二者根据SSL协议,完成身份认证、加密算法,加密密钥的确定。其保证了前者保证了通讯双方不会遭受中间人攻击,后者保证通讯的内容在传输时是出于密文状态,不会被第三方抓包泄露信息。下面我主要来讲解HTTPS详细流程。
如何证明你是你?在网络中,这个问题是必须解决的。中间人攻击是网络中典型的一种隐私信息泄露途径,黑客冒充服务端,与客户端建立起通讯,而在另一边黑客又冒充客户端,与服务端进行通讯。数据在黑客这里进行中转,在他眼中通讯双方的数据能够轻易窃取。而防止这种攻击的方法,就是使用证书证明你是你,而不是黑客。
证书的获取途径一般由二类:
1、用户自己生成私钥文件和证书请求文件
2、用户将证书请求文件提交给第三方认证机构CA
3、CA根据证书请求文件签发证书文件给用户
第二种是CA直接将证书文件和私钥文件给用户,文件结构如下:
下面讲述使用证书证明你是你的流程:
1、客户端发送支持的算法列表、随机数给服务端
2、服务端选择双方所能支持的安全性最高的算法及服务端的证书和随机数给客户端
3、客户端对证书进行校验,通过后生成一个PEM密钥,并用服务端的公钥加密PMS密钥,将PEM密文发送给服务端
4、服务端使用私钥解密PMS密文,获取到PMS密钥。
5、客户端和服务端根据PMS密钥+第一步随机数+第二步随机数,计算出四个密钥,分别是用于服务端加密数据使用的密钥Key1,服务端
防篡改使用的密钥MacKey1,客户端加密数据使用的密钥Key2,客户端防篡改使用的密钥MacKey2.
6、服务端针对1-4步骤涉及到的通讯报文,使用MacKey1进行计算,并将计算结果MAC值发送给客户端
7、客户端使用MacKey1对服务端发送的MAC进行校验,判断报文没有被篡改后进行下一步
8、客户端针对1-4步骤涉及到的通讯报文,使用MacKey2进行计算,并将计算结果MAC值发送给服务端
9、服务端使用MacKey2对服务端发送的MAC进行校验,判断报文没有被篡改,则HTTPS协商完成,开始数据通信。
下面根据上述流程,我简单讲解下初学者常遇到的问题。
1、为什么协商完四组密钥后,通讯双发需要互相发送一次MAC值?
答:由于在上述第五步骤,双发协商出对称密钥前,通讯都是使用明文通讯,内容有被篡改的风险。假设第三方在第一个步骤,客户端发送支持算法列表前,将安全程度高的算法给剔除。那么服务端只能选择安全程度低的算法进行HTTPS通讯。
2、为什么协商密钥需要用到二组随机数?
答:为了防止重放攻击,假设使用固定的字符串或者干脆不使用,直接由PMS计算出四组密钥。那么第三方可以先截获服务端和客户端从协商到通讯阶段的所有报文。由于协商阶段没有随机数的存在,第三方可以将协商阶段的报文重复发送给服务端,服务端将判断该次通讯正常,并成功建立起HTTPS通讯,通过这个手段,黑客可以进行一些恶意动作,例如重复下订单。
下面我将举例在GIN框架中,开启HTTPS协议,更安全的保障WEB服务。
首先我们准备一个证书文件和密钥文件。
如果你没有,那么你可以通过以下二个地址获取到,当然它不使用权威的第三方机构,只能用来学习。
获取密钥文件和证书请求文件:https://www.chinassl.net/ssltools/generator-csr.html
获取证书文件:https://www.chinassl.net/ssltools/free-ssl.html
package main
import (
"github.com/gin-gonic/gin"
)
func main(){
r := gin.Default()
v1 := r.Group("/v1/top")
v1.GET("/:usrname", func(context *gin.Context) {
context.String(200, "获取用户名为%s的帖子", context.Param("usrname"))
})
// 第一个参数是服务器开启地址,第二个参数是证书文件地址,第三个参数是密钥文件地址,
r.RunTLS("127.0.0.1:8080", "D:/Programme/test/Server.crt", "D:/Programme/test/Server.key")
}