SSL证书验证在Java中失败,但在其他任何地方都有效
在用Java代码访问我们自己的网站时,会引发一个异常:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching en.greatfire.org found.
但是,在浏览器中访问它或使用curl时,没有问题
知道为什么会这样吗?如果我们的证书有任何问题,但浏览器不知何故更加宽松,我们希望解决它
不确定是否相关,我们有greatfire的单独证书。org和en。大火。组织
引发上述异常的Java代码:
URL url = new URL("https://en.greatfire.org");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
System.out.println("Response code: " + conn.getResponseCode());
for(Entry<String, List<String>> header : conn.getHeaderFields().entrySet()) {
for(String headerValue : header.getValue()) {
System.out.println(header.getKey() + ": " + headerValue);
}
}
# 1 楼答案
RFC 2818 (the HTTPS specification)说:
本质上,如果根本没有SAN扩展,它应该在主题DN中使用CN,否则,它应该只使用SAN条目。(最近的RFC 6125也遵循这些原则。)
听起来您的证书有一个或多个SAN条目,但没有一个对您要查找的主机名有效(可能仅在CN中)
Java在这方面非常严格,包括SAN条目的类型(例如IP addresses),但有些浏览器更宽松。我建议通过将所有要使用的主机名(或IP地址)放在主题替代名称中来修复证书
编辑:
话虽如此,你有几个相关的问题
您为
en.greatfire.org
提供的证书中有en.greatfire.org
和www.en.greatfire.org
的SAN条目,这很好,应该可以使用但是,如果您使用的客户端不支持SSL/TLS服务器名称指示扩展(例如
openssl s_client -showcerts -connect en.greatfire.org:443
,或者Java 6),那么您将获得greatfire.org
和www.greatfire.org
的证书这是一个双重问题,因为:
greatfire.org
甚至无法解析同一台机器李>看起来你的一个证书还可以,但不支持SNI的客户端将无法看到它。 如果要避免此问题,请获取对所有4个名称(4个SAN条目)有效的证书,并将
greatfire.org
指向正确的IP地址