Java (JSSE HostnameChecker)Java
错误信息
No subject alternative names present
也可能输出为
- java.security.cert.CertificateException: No subject alternative names present
JDK 21 及更高版本会在异常文本前加上“(certificate_unknown) ”。对于 DNS 主机名,没有 SAN 的证书在 Java 中仍可能通过通用名称匹配;其他客户端(Go、Chrome)会直接拒绝这类证书。
Java (JSSE HostnameChecker) — certificate without a SAN extension, URL host is an IP address
含义
服务器证书完全没有主题备用名称(SAN)扩展,而客户端是通过 IP 地址连接的。对于 IP 地址,Java 要求有 IP SAN 条目,并且从不回退到通用名称(CN),所以没有 SAN 扩展就没有可比较的内容。这种情况通常出现在旧脚本生成的、只有 CN 的证书上。
原因
证书创建时没有 subjectAltName
常见不带 -addext subjectAltName 的 openssl req -x509、不带 -ext SAN 的旧 keytool 命令,或者由设备自动生成的证书。
IP 地址被放进了通用名称
常见CN=10.0.0.5 看起来没问题,但在 IP 匹配时会被忽略;只有 IP SAN 条目才算数。
旧的 PKI 工具或模板
偶见早于 SAN 要求出现的内部 CA 模板,仍在签发只有 CN 的证书。
修复方法
- 1.
确认 SAN 扩展确实缺失
打印主体和 subjectAltName;如果没有输出 SAN,就说明证书必须重新签发。
bash openssl x509 -in server.pem -noout -subject -ext subjectAltName # "No extensions in certificate" / no SAN output -> the certificate must be reissued - 2.
带上 subjectAltName 重新签发
添加 DNS 条目,必要时也添加 IP 条目;CN 只保留用于显示。
bash openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com" \ -addext "subjectAltName=DNS:api.example.com,IP:10.0.0.5" # keytool (Java keystores) keytool -genkeypair -alias server -keyalg EC -groupname secp256r1 -dname "CN=api.example.com" \ -ext "SAN=dns:api.example.com,ip:10.0.0.5" -keystore server.p12 -storepass changeit