获取与证书匹配的所有主机名列表
如何获取与证书 (java.security.cert.X509Certificate
) 匹配的所有主机名和 IP 的列表,包括主题替代名称?我只找到了 javax.net.ssl.HostnameVerifier
s 的各种实现.
How to get list of all hostnames and IPs that will match certificate (java.security.cert.X509Certificate
) including also subject alternative names? I've only found various implementations of javax.net.ssl.HostnameVerifier
s.
推荐答案
主机名验证如何与证书绑定在 RFC 2818,第 3.1 节(对于 HTTPS,对于其他协议,请参阅 RFC 6125,但非常相似).
How host name verification is tied to certificates is defined in RFC 2818, Section 3.1 (for HTTPS, for other protocols, see RFC 6125, but it's very similar).
简而言之:
- 使用您的
X509Certificate
实例,并遍历getSubjectAlternativeNames()
. - 每个条目都是一个 2 元素列表.第一个是类型,第二个是实际值.
- 类型 2 用于 DNS 名称,类型 7 用于 IP 地址.您需要分别对待它们.
- 如果有任何 SAN IP 地址条目,请将这些地址添加到您的 IP 地址列表中.
- 如果有任何 SAN DNS 名称条目,请将这些名称添加到您的 IP 地址列表中.
- 如果没有任何 SAN DNS 名称条目(但可能仍有 IP SAN AFAIK),您可以读取证书的主题 DN 并提取其 CN(通用名称)并将其添加到您的列表中.(有关如何提取 CN,请参阅this question.请注意,RFC 2818 中最具体的"CN 的概念是RFC 6125 中承认并解决了歧义.)
- Using your instance of
X509Certificate
, and iterate through the result ofgetSubjectAlternativeNames()
. - Each entry will be a 2-element list. The first one is the type, the second is the actual value.
- Type 2 is for DNS names, type 7 is for IP addresses. You'll need to treat them separately.
- If there are any SAN IP address entries, add these addresses to your list of IP addresses.
- If there are any SAN DNS names entries, add these names to your list of IP addresses.
- If there aren't any SAN DNS names entries (but there may still be have IP SANs AFAIK), you can read the Subject DN of the certificate and extract its CN (Common Name) and add it to your list. (See this question on how to extract the CN. Note that the notion of "most specific" CN in RFC 2818 was an ambiguity acknowledged and addressed in RFC 6125.)
请注意,证书中的某些主机名可能包含通配符,因此您将无法构建可能匹配项的详尽列表.通配符的这个问题当然是编写验证器通常比尝试获取完整列表更有意义的原因之一.(有关该位置的详细信息,请阅读 RFC 2818 第 3.1 节,并记住点本身不是通配符表达式的一部分,因此 *.example.org
与 example 不匹配.org
.)
Note that some of the host names in the certificates may contain wildcards, hence you won't be able to build an exhaustive list of possible matches. This problem with wilcards is certainly one of the reasons it usually makes more sense to write a verifier than trying to get a complete list. (Read RFC 2818 Section 3.1 for details about the position, and keep in mind that the dot itself isn't part of the wildcard expression, so *.example.org
doesn't match example.org
.)
相关文章