配置国密(SM2)证书的多域名SAN扩展,核心思路与国际证书类似。目前最主流的方法是通过精心配置 `openssl.cnf` 文件,并使用支持国密算法的 OpenSSL 分支(如 GmSSL)来生成签名请求(CSR)和证书。
方法一:使用 GmSSL + OpenSSL 配置文件
GmSSL是OpenSSL的一个分支,是生成国密证书的官方参考工具。你需要将私钥算法指定为 `SM2`,这主要通过配置文件实现。
1. 安装 GmSSL
你可以从其官方网站下载,或通过源码编译安装。
2. 准备配置文件 (gmssl-san.cnf)这是最关键的一步。你需要创建一个新的配置文件,或者修改现有的 `openssl.cnf`。以下是一个完整的 `gmssl-san.cnf` 示例:
ini
[ req ]
default_bits = 2048
default_md = sm3
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = Example Ltd.
organizationalUnitName = IT Dept.
commonName = www.example1.com
[ v3_req ]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = www.example1.com
DNS.2 = example1.com
DNS.3 = secure.example2.com
DNS.4 = api.example3.cn
3. 生成私钥 (PEM 格式)
bash
gmssl ecparam -genkey -name sm2p256v1 -out server.key
`-name sm2p256v1`: 指定使用标准SM2曲线。
4. 生成 CSR (证书签名请求)
bash
gmssl req -new -key server.key -out server.csr -config gmssl-san.cnf
5. (可选)使用自己的CA签发证书
bash
gmssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extensions v3_req -extfile gmssl-san.cnf
方法二:使用普通 OpenSSL + 配置文件
理论上可行,但你可能需要手动编译一个支持国密算法的 OpenSSL 版本。其配置方法与 GmSSL 完全相同。
方法三:使用 Java keytool 工具
如果你的应用基于 Java 环境,可以使用 Java 自带的 `keytool` 命令,通过 `-ext` 参数快速添加 SAN,简单方便。
bash
keytool -genkeypair -alias server -keyalg EC -keysize 256 -sigalg SM3withSM2 \
-keystore server.jks -validity 365 -dname "CN=test.com, OU=IT, O=Example, L=Beijing, ST=Beijing, C=CN" \
-ext "SAN=dns:test.com,dns:www.test.com,dns:api.example.com" \
-storepass password -keypass password
方法四:使用 CFSSL 工具
对于需要自动化签发和管理的场景,CFSSL 非常合适。你需要为其编写一个 SON 配置文件,国密 SM2 的配置示例如下:
1. 准备配置文件 (gmserver.json)
json
{
"CN": "www.example1.com",
"hosts": [
"www.example1.com",
"example1.com",
"secure.example2.com",
"api.example3.cn"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "Beijing",
"O": "Example Ltd.",
"OU": "IT Dept."
}
]
}
2. 生成私钥和 CSR 请求文件
bash
cfssl gencert -initca gmserver.json | cfssljson -bare server
如何验证生成的证书
成功生成证书后,务必验证 SAN 扩展是否已正确写入。可使用以下命令查看详细信息:
bash
gmssl x509 -in server.crt -noout -text
在输出信息中,找到 `X509v3 Subject Alternative Name` 字段,确认其包含了你在配置文件中定义的所有 DNS 条目。
重要提醒
国密双证书:在金融等高安全场景中,国密 SSL 要求使用签名证书和加密证书。在这种情况下,你需要为这两个证书各自生成私钥和 CSR,并分别配置 SAN 扩展,过程和指引一致。
工具兼容性:生成国密证书强烈推荐使用 GmSSL 或对国密算法有良好支持的工具链。不恰当地使用标准 OpenSSL 可能导致生成的证书在实际部署中出现问题。
SAN 数量限制:SAN 字段可以写入多个域名和 IP 地址,但建议数量不超过 100 个,否则可能影响证书验证效率
总结对比
GmSSL(推荐):适合所有需要生成国密证书的场景,需使用配置文件。
Java keytool:适合 Java 开发者快速生成用于开发或测试的证书,可通过 `-ext` 参数添加 SAN。
CFSSL:适合需要构建 PKI、自动化签发证书的团队,使用 JSON 配置文件。
脚本:适合需要高度自动化的场景,通常封装为 Python、Shell 等脚本,调用 GmSSL 或 OpenSSL 命令行生成。