前言
1、本来想自己写一下的,发现这篇文章写的已经非常详细了,所以就转载一下,原文地址:OpenSSL证书通过Subject Alternative Name扩展字段扩展证书支持的域名
2、建议先了解基础知识 ,可以查看我之前写的博客 OpenSSL 自建CA 以及颁发证书(网站部署https&&双向认证)
一、概述
1.1、什么是 Subject Alternative Name(证书主体别名)
1、SAN(Subject Alternative Name) 是 SSL 标准 x509 中定义的一个扩展。它允许一个证书支持多个不同的域名。通过使用 SAN 字段,可以在一个证书中指定多个 DNS 名称(域名)、IP 地址或其他类型的标识符,这样证书就可以同时用于多个不同的服务或主机上。 这种灵活性意味着企业不需要为每个域名单独购买和安装证书,从而降低了成本和复杂性。
2、先来看一看 Google 是怎样使用 SAN 证书的,下面是 Youtube 网站的证书信息:
3、 或者咸鱼的,签发的时候 CN(common name)明明是 *.goofish.com
,但是你访问 2.taobao.com
也是可以的
4、 这里可以看到这张证书的 Common Name 字段是 *.google.com,那么为什么这张证书却能够被 www.youtube.com 这个域名所使用呢。原因就是这是一张带有 SAN 扩展的证书,下面是这张证书的 SAN 扩展信息:
5、这里可以看到,这张证书的 Subject Alternative Name 段中列了一大串的域名,因此这张证书能够被多个域名所使用。对于 Google 这种域名数量较多的公司来说,使用这种类型的证书能够极大的简化网站证书的管理。
1.2、SAN 的由来
1、在早期的互联网中,每个 SSL/TLS 证书通常只包含一个 CN 字段,用于标识单一的域名或 IP 地址。随着虚拟主机技术的发展和企业对于简化管理的需求增加,需要一种机制能够允许单个证书有效地代表多个域名或服务。例如,一个企业可能拥有多个子域名,希望用单一的证书来保护它们。
2、为了解决这个问题,SAN 扩展被引入到 X.509 证书标准中。最初在 1999 年的 RFC 2459 中提出,SAN 提供了一种方法来指定额外的主题名称,从而使得一个证书能有效地代表多个实体。
1.3、 SAN 的作用和重要性
- 多域名保护:SAN 使得一个证书可以保护多个域名和子域名,减少了管理的复杂性和成本。
- 灵活性增强:企业和组织可以更灵活地管理和部署证书,根据需要快速调整和扩展保护范围。
- 兼容性:随着技术的发展,现代浏览器和客户端软件都已经支持 SAN。它们会优先检查 SAN 字段,如果找到匹配项,通常不会再回退到检查 CN。
1.4、如何使用 SAN
1、在申请 SSL/TLS 证书时,可以指定一个或多个 SAN 值。这些值通常是你希望证书保护的域名或 IP 地址。证书颁发机构(CA)在颁发证书时会验证这些信息的正确性,并将它们包含在证书的 SAN 字段中。
二、在 OpenSSL 中创建证书时添加 SAN,需要在配置文件中添加一个 subjectAltName 扩展。这通常涉及到以下几个步骤:
- 准备配置文件:在配置文件中指定 subjectAltName 扩展,并列出要包含的域名和 IP 地址。
- 生成密钥:使用 OpenSSL 生成私钥。
- 生成证书签发请求(CSR):使用私钥和配置文件生成 CSR,该 CSR 将包含 SAN 信息。
- 签发证书:使用 CA(证书颁发机构)或自签名方式签发证书,证书中将包含 SAN 信息。
2.1 准备带有 SAN 扩展的证书请求配置文件
1、创建带有 SAN 扩展字段的证书签名请求(CSR)的配置文件, alt_names 的配置段为 SAN 扩展字段配置。确保在将其保存至文件(如 csr.conf)。
[ req ] # 需要有的内容
default_bits = 2048 # 生成的长度
prompt = no # 是否还需要提示,就是我们之前那个需要你输入 服务器信息(国家 省会 城市 公司 部门 以及common name(服务器ip和域名,也叫cn),这里选择no,是因为这个文件里面包含了这些参数,就是下面的 dn 内容)
default_md = sha256 # 加密算法
req_extensions = v3_ext # req_extensions ,值是就是 当前文件下的 [v3_ext]节选
distinguished_name = dn # distinguished_name ,值是就是 当前文件下的 [dn]节选
[ dn ]
C = CN
ST = ShangDong
L = SZ
O = Wise2c
OU = Wise2c
CN = zmc
[ req_ext ]
subjectAltName = @alt_names # 值就是 当前文件下的 [alt_names ]节选
[ alt_names ]
DNS.1 = *.zmcheng.com
DNS.2 = *.zmcheng.net
DNS.3 = *.zmc.com
DNS.4 = *.zmc.net
[ v3_ext ]
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
注意 1:SAN 扩展字段不仅可以配置域名,还可以配置邮箱、IP 地址、URI。
// Subject Alternate Name values. (Note that these values may not be valid
// if invalid values were contained within a parsed certificate. For
// example, an element of DNSNames may not be a valid DNS domain name.)
DNSNames []string
EmailAddresses []string
IPAddresses []net.IP // Go 1.1
URIs []*url.URL // Go 1.10
2.2、生成ca
1、 生成ca密钥位数为 2048 的 ca.key
openssl genrsa -out ca.key 2048
2、依据 ca.key 生成 ca.crt (使用 -days 参数来设置证书有效时间):
openssl req -x509 -new -nodes -key ca.key -subj "/CN=zmc" -days 10000 -out ca.crt
2.3、生成server
主要是这里2,3 步骤不一样,增加参数
1、生成密钥位数为 2048 的 server.key
openssl genrsa -out server.key 2048
2、生成证书签发请求,基于配置文件生成证书签名请求(主要是这里使用配置文件csr.conf )
openssl req -new -key server.key -out server.csr -config csr.conf
3、签发证书,使用 ca.key、ca.crt 和 server.csr 生成服务器证书(主要是这里使用配置文件csr.conf )
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000 -extensions v3_ext -extfile csr.conf
4、 查看证书,可以看到创建出带有 SAN 扩展字段证书
openssl x509 -noout -text -in ./server.crt
三、客户端
(一般是浏览器)在请求 HTTPS 网站时,验证服务端证书的过程确实是一个复杂且关键的安全步骤。以下是以浏览器为例,说下浏览器验证服务端证书步骤:
- 发起 HTTPS 请求:
- 用户通过浏览器输入 HTTPS 网站的 URL,并按下回车键或点击链接,浏览器开始发起 HTTPS 请求。
- 服务端响应并发送证书:
- 服务器在收到 HTTPS 请求后,会将其 SSL/TLS 证书发送给浏览器。这个证书包含了服务器的公钥、证书颁发机构(CA)的信息、证书的有效期、以及可能包括的 SAN(主题备用名称)和 CN(通用名称 common name)等字段。
- 浏览器验证证书颁发机构(CA):
- 浏览器会检查证书是否由受信任的 CA 签发。浏览器内置了一个受信任的 CA 列表(也称为根证书列表),它会使用这些 CA 的公钥来验证证书链中每一级证书签名的有效性,直到找到信任的根证书。
- 检查证书有效期:
- 浏览器会验证证书的有效期,确保当前时间在证书的有效期内。
- 验证证书域名:
- 浏览器会检查证书中的 SAN 字段(如果存在)和 CN 字段,确保它们与用户正在访问的域名相匹配。如果域名不匹配,浏览器将认为证书无效,并显示警告信息。
- 检查证书吊销状态(可选):
- 浏览器可能会通过 OCSP(在线证书状态协议)或 CRL(证书吊销列表)来检查证书是否已被吊销。这一步是可选的,但有助于及时发现并阻止使用已泄露私钥的证书。
- 生成会话密钥(TLS 握手过程的一部分):
- 如果证书验证通过,浏览器和服务器将进行 TLS 握手,以协商一个安全的会话密钥。这个密钥将用于后续通信的加密和解密。
- 加密通信:
- 一旦会话密钥协商完成,浏览器和服务器就可以开始加密通信了。浏览器会使用会话密钥加密发送给服务器的数据,而服务器则使用相同的会话密钥解密这些数据。
注意事项
- 如果浏览器在验证证书的过程中发现任何问题(如证书不受信任、已过期、域名不匹配等),它将向用户显示警告信息,并可能阻止用户继续访问该网站。
- SAN 字段的优先级通常高于 CN 字段。如果证书中同时包含了 SAN 和 CN 字段,并且它们之间的域名不一致,浏览器将优先使用 SAN 字段中的域名进行验证。
- 浏览器内置的受信任 CA 列表可能会随着时间的推移而更新,以反映新的 CA 或撤销旧的 CA。因此,用户应该保持其浏览器和操作系统的更新,以确保其能够识别最新的受信任 CA。
以上步骤详细描述了浏览器在请求 HTTPS 网站时验证服务端证书的过程。这个过程确保了用户与服务器之间的通信是安全、可信的。