SSL证书颁发机制与方式
这篇文章讲一下申请SSL证书的几种流程,包括Web、ACME等方式。
SSL证书签发机制
CA(Certificate Authority,证书颁发机构)是互联网中的“可信第三方”,负责验证域名所有权并签发SSL/TLS证书。
CA的核心职责不是为域名生成密钥对,而是对用户生成的公钥进行签名,证明这个公钥确实属于某个身份,如域名、企业等。
浏览器之所以信任某个网站的证书,不是因为信任网站本身,而是因为该证书最终能够追溯到浏览器或操作系统内置的受信任根CA。像Let's Encrypt、DigiCert、Sectigo等都是被主流浏览器信任的公开CA,而腾讯云、阿里云等证书申请平台通常只是代办或管理平台,真正签发证书的仍然是这些CA。
判断一个CA是否可信,最简单的方法就是看它的根证书是否被Chrome、Firefox、Windows、macOS等主流系统和浏览器默认信任。
此外,如果一个恶意SSL证书被浏览器/系统信任,那么这个恶意证书所有者便可以伪装服务端,对客户端发起中间人攻击。
Web端申请
这是最传统的SSL证书申请方式,流程如下:
登录证书申请网站——>填写申请域名信息——>完成域名验证——>下载证书——>部署证书
常见的证书申请平台包括ZeroSSL、腾讯云SSL证书服务、阿里云SSL证书服务等。
其中,DNS TXT记录验证是目前最常见的方式之一,通过在域名的DNS配置中添加指定的TXT记录,证书颁发机构(Certificate Authority,CA)即可验证申请者对域名的控制权。
ACME端申请
ACME 全称:Automated Certificate Management Environment,中文一般翻译为自动化证书管理环境,它本身是一种协议,由IETF(Internet Engineering Task Force)制定。除了ACME,IETF还制定了HTTP、DNS、TCP/IP等等众多协议,包括先前博文提到的RFC文档也是这个组织发布的。
相较于繁琐的Web控制台申请方式,ACME是目前最主流的SSL证书申请方式,其大致流程如下:
安装ACME客户端——>向CA发起证书申请——>CA下发Challenge——>客户端自动完成域名验证——>CA签发证书——>客户端自动下载证书——>部署证书
在RFC 8737中,ACME的Challenge一共就3种,如下表所示:
| Challenge | 验证方式 | 端口需求 | 支持泛域名 |
|---|---|---|---|
| HTTP-01 | Web 服务 | 80 | 否 |
| DNS-01 | DNS 记录 | 无 | 是 |
| TLS-ALPN-01 | TLS 服务 | 443 | 否 |
下面详细介绍3种Challenge的认证机制
HTTP-01
在ACME协议中,HTTP-01 Challenge是最常见的域名所有权验证方式。
其核心思想是:通过验证申请者是否能够控制目标域名对应的Web服务,来证明其拥有该域名的管理权限。
当客户端向 CA 申请证书时,CA 会生成一个随机的 Challenge Token,并要求客户端将该 Token 按照规定格式放置在 Web 服务器的指定路径下:
http://<domain>/.well-known/acme-challenge/<token>
随后,CA会主动向该URL发起HTTP请求。如果能够成功获取到预期内容,则认为申请者拥有该域名的控制权,验证通过后即可签发证书。
这个临时的Web服务,通常由ACME客户端自动化轻量化提供,所以,通过这种方式签发SSL证书时,一定要确保主机80端口没有被占用。
DNS-01
DNS-01是ACME协议中基于DNS记录的域名验证方式。与HTTP-01不同,DNS-01不依赖Web服务,而是通过验证指定DNS TXT记录的内容来确认申请者拥有目标域名的控制权。
由于域名解析记录通常只有域名管理者才能修改,因此能够成功创建指定TXT记录即可证明对该域名拥有管理权限。
当客户端向 CA 申请证书时,CA 会生成一个随机 Challenge Token,并要求客户端在目标域名下创建一条特定的 TXT 记录:
_acme-challenge.<domain>
客户端将计算得到的 Challenge Value 写入该 TXT 记录后,CA 会主动查询 DNS 服务器。
如果查询结果与预期内容一致,则验证通过,CA 随后签发证书。
通过ACME客户端申领时,由于要配置DNS解析,所以要提供DNS服务商的API凭证,以确保ACME客户端能够自动化配置DNS解析。
这种方式其实和Web端申领SSL证书的原理一样。
TLS-ALPN-01
与HTTP-01通过HTTP文件验证不同,TLS-ALPN-01通过TLS握手过程中的ALPN(Application-Layer Protocol Negotiation)扩展完成域名所有权验证。
该方式要求申请者能够控制目标域名对应的 HTTPS 服务,因此常用于无法开放80端口但能够开放443端口的场景。
当客户端申请证书时,CA会生成一个Challenge Token,并要求客户端在443端口提供一个特殊的临时证书。
随后,CA会与目标域名建立TLS连接,并在TLS握手阶段通过ACME专用的 ALPN 标识,acme-tls/1请求验证。
如果服务器返回的临时证书中包含正确的Challenge信息,则验证通过,CA随后签发正式证书。
自签证书
除了上述两种证书申请模式,还有一种自签证书。
自签名证书是由证书持有者自行签发的数字证书,其签发者(Issuer)和主体(Subject)为同一实体。
与由公开证书颁发机构(CA)签发的证书不同,自签名证书不需要经过第三方机构认证,因此浏览器和操作系统默认不会信任该证书。
使用OpenSSL可快速生成自签名证书:
openssl req \
-x509 \
-newkey rsa:2048 \
-nodes \
-keyout server.key \
-out server.crt \
-days 365
生成文件:
server.key 私钥
server.crt 自签名证书
随后即可配置到Nginx、Apache或其他TLS服务中使用。
此外,自签证书可以随时将公钥发送给CA机构进行签名,签名后即可受浏览器或操作系统信任。
ACME客户端介绍
常见 ACME 客户端
ACME客户端负责与CA通信、完成Challenge验证、申请证书以及自动续期。当前主流的 ACME 客户端如下:
| 客户端 | 平台 | 开发语言 | 特点 |
|---|---|---|---|
| Certbot | Linux/Unix | Python | 官方推荐,功能完善 |
| acme.sh | 跨平台 | Shell | 轻量级,DNS API 支持丰富 |
| lego | 跨平台 | Go | 单文件程序,易于集成 |
| win-acme | Windows | C# | 适用于 IIS 和 Windows Server |
| cert-manager | Kubernetes | Go | Kubernetes 原生证书管理 |
比如,使用acme.sh,可通过以下命令迅速签发一个SSL证书
~/.acme.sh/acme.sh --issue --standalone --domain example.com
所以,由于ACME协议的便捷性,已经成为SSL证书申请的主流方式。