跳到主要内容
ecdsa.com
Go crypto/x509Go

错误信息

x509: certificate is not valid for any names, but wanted to match api.example.com

也可能输出为

  • tls: failed to verify certificate: x509: certificate is not valid for any names, but wanted to match api.example.com

“wanted to match”后面的名称就是你连接的目标。对于完全没有 SAN 扩展的证书,Go 报出的则是“x509: certificate relies on legacy Common Name field, use SANs instead”(前提是 CN 本来可以匹配)。

Go crypto/x509 — HostnameError for a certificate with no DNS SANs (e.g. IP-only or empty SAN list)

含义

Go 尝试将主机名与证书匹配,却根本找不到任何 DNS 名称:SAN 扩展是存在的,但只包含 IP 地址(或其他类型的条目),而通用名称不在考虑范围内。Go 会报告证书不覆盖任何名称,后面跟着它想要匹配的名称。

原因

修复方法

  1. 1.

    检查 SAN 条目和证书用途

    SAN 列表显示存在哪些类型的名称;extendedKeyUsage 显示它到底是不是服务器证书。

    bash
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \
      | openssl x509 -noout -subject -ext subjectAltName,extendedKeyUsage
  2. 2.

    签发带 DNS 类型 SAN 的服务器证书

    写入客户端使用的 DNS 名称;如果客户端也通过地址连接,再加上 IP 条目。

    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"
  3. 3.

    或者通过证书中列出的地址连接

    只有当客户端连接的正是该 IP 时,IP 类型的 SAN 才会匹配。

    go
    // If the certificate is meant for the IP address, dial the IP (it is matched against IP SANs)
    resp, err := client.Get("https://10.0.0.5:8443/")

相关错误

浏览完整的签名错误库