超文本传输协议 HTTP 作为一种无状态无连接的协议,在传输信息时采用的是明文的方式,因此传输过程中的信息存在着被窃听、被篡改和被劫持的风险。因此,当你的引用涉及诸如共享密码、银行卡等私密信息时,单纯的使用 HTTP 显然是无法高效地对信息进行有效的加密和保护的。此时,就需要对涉及隐私的网站启用 HTTPS 了,HTTPS 实际就是将 HTTP 通信放到了具有安全性的 SSL/TSL 上进行加密传输的协议。
SSL、TLS 和 HTTPS
SSL(Secure Socket Layer,安全套接字层),是一种通过公钥基础设施(Public Key Infrastructure,PKI)为通信双方提供数据加密和身份验证的协议,其中通信双方通常是客户端和服务器。SSL 协议于 1994 年被 Netscape 公司发明,后来各个浏览器均逐渐开始支持 SSL 协议。之后由 IETF(Internet Engineering Task Force,互联网工程任务组)接受并在 SSL 3.0 协议规范的基础上,制定了 TLS (Transport Layer Security,安全传输层协议),TLS 与 SSL 之间的加密算法不同,因此两者存在着显著差异,但是在理解 HTTPS 的过程中,可以把 SSL 和 TLS 看成是同一种协议,也就是说 HTTPS 实际上就是在 SSL/TLS 连接的上层进行 HTTP 通信。
要为你的 Web 应用提供 HTTPS 服务,你需要使用 SSL/TLS 证书来实现数据加密以及身份验证。而为了保证证书的可靠性,证书一般由 CA(Certificate Authority,证书分发机构)签发。
HTTPS 为了兼顾效率和安全,当服务器接收到客户端发送的请求之后,会将证书和响应一并返回给客户端,而客户端在确认证书的真实性之后,就会生成一个随机密钥(random key),并使用证书中的公钥对随机密钥进行加密,此次加密产生的对称密钥(symmetric key)就是客户端和服务器进行通信时,负责对通信实施加密的实际密钥。那 SSL 证书举例,它是一种使用 X.509 格式进行格式化的数据,这些数据包含了公钥以及其他一些相关信息。
一个 X.509 证书(简称 SSL 证书)实际上就是一个经过编码的 ASN.1(Abstract Syntax Notation One,抽象语法表示法/1)格式的电子文档。ASN.1 既是一个标准,也是一种表示法,该标准包含了公钥证书的标准格式,同时描述了表示电信以及计算机网络数据的规则和结构。
X.509 有多种格式编码,其中一种是 BER(Basic Encoding Rulues,基本编码规则),指定了一种自解释并且自定义的格式用于对 ASN.1 数据结构进行编码,而 DER 格式则是 BER 的一个子集(后续代码会提到),DER 只提供了一种编码 ASN.1 值的方法。SSL 证书有多种不同的格式保存,其中一种是 PEM(Privacy Enhanced Email,隐私增强邮件)格式,该格式会对 DEM 格式的 X.509 证书实施 Base64编码,这种格式的文件都以 -----BEGIN CERTIFICATE-----
开头,以 -----END CERTIFICATE-----
结尾。
提供 HTTPS 服务
假设你已经获取了 SSL/TLS 证书文件 cert.pem
,以及服务器私钥文件 key.pem
,那么我们在使用的时候,只需要用一行代码即可启动
1 | server := http.Server{ |
假如我们是在测试环境中,我们想要测试一下证书和私钥,那么我们完全可以使用自己生成的证书。虽然自行生成的证书和私钥不会用在生产环境中,但是了解 SSL 证书和私钥的生成方法,并学会如何在开发和测试的过程中使用证书和私钥,也是一件非常有意义的事情。
生成个人使用的 SSL 证书以及服务器私钥
生成 SSL 证书和密钥的步骤并不是特别复杂。因为 SSL 证书实际上就是一个将扩展密钥用法(extended key usage)设置成了服务器身份验证操作的 X.509 证书,所以在下面的代码中会使用 crypto/x509
标准库。此外,因为创建证书需要用到私钥,所以程序在使用私钥成功创建证书之后,还需将私钥单独保存在一个存放服务器私钥的文件里面。
1 | package ssl |
值得注意的是,若证书是由 CA 签发,那么证书文件中将同时包含服务器签名以及 CA 签名,其中服务器前面在前,CA 签名在后
引用
- Sau Sheong Chang.Go Web 编程[M].人民邮电出版社:北京,2017:53-56.