我尝试创建与网站(https://www.otten-markenshop.de/)的SSL连接,并使用浏览器或卷曲它可以工作,但是没有wget,没有Java设法连接。我最感兴趣的是为什么Java代码会失败。 以下是错误详细信息:
使用WGET:
wget https://www.otten-markenshop.de/
结果
Resolving www.otten-markenshop.de... 217.24.213.167
Connecting to www.otten-markenshop.de|217.24.213.167|:443... connected.
ERROR: certificate common name “www.plentymarkets.eu” doesn’t match requested
host name “www.otten-markenshop.de”.
使用Java:
public static void main(String[] args) throws IOException
{
URL url = new URL("https://www.otten-markenshop.de");
URLConnection connection = url.openConnection();
connection.getInputStream();
}
结果:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
java.security.cert.CertificateException: No subject alternative DNS
name matching www.otten-markenshop.de found.
我注意到的是,我在浏览器中收到的证书与运行Java程序时收到的证书不同:
浏览器中的:
Common Name (CN):
www.otten-markenshop.de
Subject Alternative Name:
DNS Name=www.otten-markenshop.de
DNS Name=otten-markenshop.de
Java中的:
Common Name (CN):
www.plentymarkets.eu
Subject Alternative Name:
如果我尝试通过IP地址访问主机,那么我在Java中获得的证书与在浏览器中获得的证书相同:https://217.24.213.167
因此,服务器似乎安装了多个证书,并使用虚拟主机来检测应使用哪个证书。但由于某些原因,当客户端是Java或wget时,此检测不起作用。
任何想法为什么会发生这种情况?
P.S。我无法访问目标服务器以查看其配置方式。
P.P.S。我更感兴趣的是理解为什么简单的Java代码不起作用,而不是让它工作,例如,禁用SSL验证。毕竟我可以通过HTTP连接到提到的URL而没有任何问题。
答案 0 :(得分:1)
在同一IP地址和端口上拥有多个证书依赖于服务器名称指示。
您的服务器支持它,但您的客户也需要支持它。
客户端对SNI的支持仅在Java 7中引入Java(参见release notes)(*)。我猜您使用的是Java 6或更低版本,否则您使用URLConnection
的简单示例应该像这样开箱即用。
(如果您正在使用其他客户端库,例如Apache HTTP Client,则可能还需要其他设置,具体取决于版本。)
(*)这是在Java 8的服务器端引入的,但这不是你的问题。