这里不详细说明 TLS 协议的内容,请另行查阅文档
画外:由于 RSA/ECC 两类非对称加密算法被广泛的应用在各类加密通讯中,因此下面说明的证书生成、签名过程,
同样也适用于其他场景,比如 SSH 密钥对生成、JWT 密钥对生成等等。
TLS 协议
我们需要加密网络数据以实现安全通信,但是有一个现实的问题:
- 非对称加密算法(RSA/ECC 等)可以方便地对数据进行签名/验证,但是计算速度慢。
- 对称加密算法(ChaCha20/AES 等)计算速度快,强度高,但是无法安全地生成与保管密钥。
于是 TLS 协议在握手阶段使用非对称算法验证服务端,并安全地生成一个对称密钥,然后使用对称算法进行加密通信。
这里讲「安全地生成一个对称密钥」(Elliptic Curve Diffie-Hellman (ECDHE) key exchange),提供了「完美前向保密(Perfect Forward Secrecy)」特性,前向保密能够保护过去进行的通讯不受密码或密钥在未来暴露的威胁。(tls1.1/tls1.2 也可以使用非前向安全的算法!要注意!)
TLS 通过两个证书来实现服务端身份验证,以及对称密钥的安全生成:
- CA 证书(公钥):浏览器/操作系统自带,用于验证服务端的 TLS 证书的签名。保证服务端证书可信。
- TLS 证书:使用 CA 证书验证了 TLS 证书后,将使用这个 TLS 证书进行协商,以安全地生成一个对称密钥。
CA 证书和 TLS 证书,都只在 TLS 握手阶段有用到,之后的通信就与它们无关了。
一、TLS 证书支持保护的域名类型
TLS 证书支持配置多个域名,并且支持所谓的通配符(泛)域名。
但是通配符域名证书的匹配规则,和 DNS 解析中的匹配规则并不一致!
根据证书选型和购买 - 阿里云文档 的解释,通配符证书只支持同级匹配,详细说明如下:
- 一级通配符域名:可保护该通配符域名(主域名)自身和该域名所有的一级子域名。
- 例如:一级通配符域名
*.aliyun.com
可以用于保护aliyun.com
、www.aliyun.com
以及其他所有一级子域名。
但是不能用于保护任何二级子域名,如xx.aa.aliyun.com
- 例如:一级通配符域名
- 二级或二级以上通配符域名:只能保护该域名同级的所有通配域名,不支持保护该通配符域名本身。
- 例如:
*.a.aliyun.com
只支持保护它的所有同级域名,不能用于保护三级子域名。
- 例如:
要想保护多个二三级子域,只能在生成 TLS 证书时,添加多个通配符域名。
因此设计域名规则时,要考虑到这点,尽量不要使用层级太深的域名!有些信息可以通过 -
来拼接以减少域名层级,比如阿里云的 oss 域名:
- 公网:
oss-cn-shenzhen.aliyuncs.com
- 内网:
oss-cn-shenzhen-internal.aliyuncs.com
二、TLS 证书的生成
前面讲到了 TLS 协议的握手需要使用到两个证书:
- TLS 证书(服务端证书):这个是服务端需要配置的数据加密证书。
- 服务端需要持有这个 TLS 证书本身,以及证书的私钥。
- 握手时服务端需要将 TLS 证书发送给客户端。
- CA 证书:这是受信的根证书,客户端可用于验证所有使用它进行签名的 TLS 证书。
- CA 证书的私钥由权威机构持有,客户端(比如浏览器)则保有 CA 证书的公钥。
在 TLS 连接的建立阶段,客户端(如浏览器)会使用 CA 证书的公钥对服务端的证书签名进行验证,验证成功则说明该证书是受信任的。
0. TLS 证书的类型
证书有两种类型:
- 向权威CA机构申请得到的 TLS 证书:这类证书会被浏览器、小程序等第三方应用/服务商信任。申请证书时需要验证你的所有权,也就使证书无法伪造。
- 如果你的 API 需要提供给这些第三方应用/服务商访问,那就必须申请此类证书。
- 由本地 CA 证书签名的 TLS 证书:这类证书不会被浏览器、小程序等第三方应用/服务商信任,证书就可以被伪造。
- 这类证书的缺点是无法与第三方应用/服务商建立安全的连接。
- 如果客户端是完全可控的(比如是自家的 APP),那可以自行验证证书的可靠性(公钥锁定、双向 TLS 验证)。这种场景下自签名证书是安全可靠的。可以不使用权威CA机构颁发的证书。
总的来说,权威CA机构颁发的证书,可以被第三方的应用信任,但是自己生成的不行。
而越贵的权威证书,安全性与可信度就越高,或者可以保护更多的域名。
在客户端可控的情况下,可以考虑使用自签名证书(方便、省钱),将这个证书预先埋入客户端中用于验证。
1. 向权威CA机构申请受信 TLS 证书
免费的 TLS 证书有两种方式获取:
- 部分 TLS 提供商有提供免费证书的申请,有效期为一年,但是不支持泛域名。
- 申请 Let's Encry