hor*_*rgh 6 java apache https tomcat solaris
据我了解,在大多数情况下,此异常表明证书所有者 CN(公用名)与 url 中的主机名不匹配。然而就我而言,它们确实匹配,但异常仍然出现。
远程服务器证书层次结构是:
CN=sms.main.ruCN=client.sms.main.ru我的 java 客户端在 apache-tomcat 6 下启动并尝试连接https://client.sms.main.ru/并抛出以下异常:
No name matching client.sms.main.ru found
Run Code Online (Sandbox Code Playgroud)
这两个证书都添加到$JAVA_HOME/jre/lib/security/cacertsvia中,如unixtippse 的答案中的How do you configure Apache/Tomcat to trust服务器到服务器 https 请求的内部证书颁发机构$JAVA_HOME/bin/keytool所示。
Java 代码非常简单:
URL url = new URL(strurl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Connection", "close");
con.setDoOutput(true);
con.connect();
Run Code Online (Sandbox Code Playgroud)
我缺少什么?
有趣的是,当我尝试在 Windows PC 上使用浏览器访问此 url 时,它说该证书不受信任,我将其添加到浏览器例外列表中,并且工作正常。所以看起来我cacerts错误地添加了这些证书,因此 java 无法使用它们。但我可以通过别名或 CN 轻松找到它们:
$JAVA_HOME/bin/keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts | less
Run Code Online (Sandbox Code Playgroud)
最后我所要做的就是:
禁用主机名验证:
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
Run Code Online (Sandbox Code Playgroud)确保cacerts使用默认文件,因为在研究时我尝试禁用 ssl 证书验证并使用可以在 SO 上的大量线程中找到的代码(实现自己的X509TrustManager),即在Java 中:覆盖函数以禁用 SSL 证书检查。这段代码替换了SSLSocketFactory我需要的 default 。因此,我必须删除所有这些内容并仅使用禁用主机名验证的代码。
我离开了HttpURLConnection。无需将其替换为HttpsURLConnection.
如果我也设法避免禁用主机名验证,那肯定会好得多,但我做不到。可能是证书有问题。。