现如今的 Web,HTTPS 早已经成为标配,公开的 HTTP 网站已经和 Flash 一样,慢慢在消亡了。
启用 HTTPS 的核心是一个叫做 证书 的东西。不知道大家是否有留意,前几年上 12306 的时候,浏览器都会提示「您的链接不是私密链接」,这其实就是因为 12306 的证书有问题。如果点击「继续前往」,打开 12306 网站,它会提示你下载安装它提供的“根证书”。
那么,证书是什么?里面含有什么内容?浏览器为什么会不信任 12306 的证书?为什么下载 12306 提供的根证书就可以解决这个问题?根证书又是什么?
证书,公钥和私钥
我们先来简单回顾一下 TLS 和 HTTPS。关于这个话题,我在 从零开始搭建一个 HTTPS 网站 这篇博客中有详细的论述,对细节感兴趣的朋友可以先去读一下这篇博客。
HTTPS 全称是 HTTP Over TLS,也就是使用 TLS 进行 HTTP 通信。
TLS (Transport Layer Security) 是一个安全通信协议,用于建立一个安全通道来交换数据。
看名字可以知道这是一个传输层协议,因此应用层协议对它是没有感知的,HTTP, FTP, SMTP 都可以和 TLS 配合使用。
TLS 创建安全链接的步骤如下:
- 双方协商使用的协议版本,加密算法等细节
- 服务器发送 证书 给客户端
- 客户端校验证书有效性
- 双方根据握手的一些参数生成一个对称秘钥,此后所有的内容使用这个秘钥来加密
我们先来看证书,证书是一个文件,里面含有目标网站的各种信息。
例如网站的域名,证书的有效时间,签发机构等,其中最重要的是这两个:
- 用于生成对称秘钥的公钥
- 由上级证书签发的签名
证书文件的格式叫做 X.509,由 RFC5280 规范详细定义。存储上分为两种,一种叫做 DER,是二进制的,还有一种叫做 PEM,是基于 Base64 的。
关于 RSA 的公钥和私钥记住一点就行:我们可以使用算法生成一对钥匙,他们满足一个性质:公钥加密的私钥可以解开,私钥加密的公钥可以解开。
证书,顾名思义,是用来证明自己身份的。因为发送证书的时候是明文的(这一步也没法加密),所以证书内容是可以被中间设备篡改的。
那么要怎样设计一套机制保证当我访问 github.com 的时候,收到的证书确实是 github.com 的证书,而不是某个中间设备随意发来的证书?
大家可以思考一下这个问题