首页 > 技术文章 > HTTPS相关知识以及在golang中的应用

hsnblog 2018-10-02 12:47 原文

最近简单学习了HTTPS,并在golang中实践了一下,现在把学到的知识记录下来,方便以后查看,如果有幸能帮到有需要的人就更好了,如果有错误欢迎留言指出。

  • 一些简单的概念,可以自行百度百科
  1. HTTPS简介:HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。
  2. HTTPS与HTTP的区别:HTTP是以明文的方式来传递数据的,HTTPS是在HTTP的基础上加入了SSL协议的加密传输方式。
  3. CA(Certificate Authority):ca就是我们所说的证书颁发机构,ca是可信的权威机构,其实就是个办证的,给他钱,他给我们办证,当然了办的都是真证。ca机构也是有证书的,我们的电脑中自带了很多ca机构的证书,这些证书被称为“根证书”,根证书的作用就是检查别人的证是不是合法的。系统中的根证书如图:
  4. 服务端证书:在使用https时,服务端要载入服务端证书服务端私钥,这里涉及到一些非对称加密的知识(简单讲,非对称加密就是有两个钥匙,公钥和私钥,用公钥加密用私钥解密,这样会安全一些,比如说,客户端要向服务器传消息,可以给服务器一个请求,拿到服务器的公钥,用服务器的公钥把数据加密,加密后的数据传给服务器,服务器收到之后用服务器端的私钥解密,拿到数据,非对称开销大,不适合大数据量传输)可以自行搜索学习一下。服务端证书就是上面提到的办证(CA)的给你办的证,你得有这个证,人家才觉得你这人靠谱,证书中呢有一些信息,例如服务端公钥,谁给你办的证(CA的签名
  5. 服务端私钥:这就是解密一些客户端发到服务器来的前置数据所用的私钥。

客户端和服务器通信时二者需要的数据:

 

客户端和服务器通信的流程:

在golang中的使用:

 首先我们要有一个服务于https的服务端,通过golang的http包,很简单的就能完成https服务端的构建

func main() {

    http.HandleFunc("/test", func(writer http.ResponseWriter, request *http.Request) {
        defer request.Body.Close()
        writer.Write([]byte("hello world"))
    })

    if err := http.ListenAndServeTLS(":8080", certPath, keyPath, nil); err != nil {
        panic(err)
    }
}

certPath和keyPath分别是服务端证书和服务端私钥的路径,在这里我用openssl生成了一个CA根证书,用这个CA根证书签发了服务器证书。

然后我将我用openssl生成的CA根证书导入浏览器中并信任该CA,然后重启chrome(不要随便导入未知的CA根证书,这很危险)

然后我们通过浏览器访问https://localhost:8080/test

ok,已经可以正常通信了。

 如果没有把根证书导入到我们的电脑中并设置信任会怎么样呢?下面我将根证书设为不信任。

再次访问https://localhost:8080/test

 

浏览器会提示你这个链接不是安全的https链接

 

数据摘要:将数据做hash之后得到的就是数据摘要。常用的算法有md5,sha1等等。

 

签名:签名就是用私钥对数据摘要进行加密,这个操作就叫做签名。

 

签名解决的问题:在非对称加密中,加密公钥是公开的,AB两个终端建立连接,发送的公钥可能会被其他人获取到,这个人获取到公钥后可能会伪装成AB其中一人向另一个人发送加密后的请求。为了防止有人冒充,引入了签名的机制来验证发送人是否合法。

 

签名验证问题:在非对称加密中,公钥用于数据加密,私钥用于数据解密,私钥也可以用于对数据签名,用公钥来验证签名。

 

签名验证的流程:非对称加密中,A要向B传送密文,B要验证接收到的数据是否是A发送的,所以A需要在向B发送密文数据时一起发送一个签名。首先将要发送的数据明文做hash,得到数据摘要,再用私钥加密数据摘要,生成签名,将签名和已加密的密文,一起发送给B,B拿到密文和签名后,用私钥对密文进行解密,解密后获得明文,对明文做hash生成数据摘要,B将A发送来的签名用A的公钥进行解密,解密后获得的数据摘要和B自己生成的数据摘要做比对,如果相同就是没有被篡改过的数据。

 

推荐阅读