尝试从安全站点生成Web服务客户端时出现奇怪的证书错误

时间:2010-03-20 02:57:40

标签: java ssl axis ssl-certificate

尝试使用AXIS1.4 Wsdl2Java工具为安全IIS站点上安装的Web服务生成客户端代码时,出现了一个奇怪的错误。当我运行该工具时,我得到以下SSL异常:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No
 name matching XXXXXXX.net found
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1
591)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
tHandshaker.java:975)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHa
ndshaker.java:123)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:5
16)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.jav
a:454)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.j
ava:884)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
LSocketImpl.java:1096)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketIm
pl.java:1123)

奇怪的是,这个错误只发生在我运行WSDL2Java时,并且只发生在这个特定的服务器上。我有另一个具有相同设置的Web服务器,一切正常。我对所有密钥库进行了三重检查,看起来所有CA证书都已正确加载。我尝试使用具有相同设置的另一台服务器,并且能够毫无问题地生成客户端代理代码。奇怪的是,如果我使用从其他服务器生成的代码对抗奇怪的服务器一切正常。只有Wsdl2Java给我一个问题。

5 个答案:

答案 0 :(得分:1)

主机的DNS名称(例如machine1.mydomain.tld)与证书中的CommonName值之间很可能不匹配,因此CertificateException不匹配。从blog post

开始
  
      
  • 如果您想通过使用IP作为主机名进行连接;
      您的证书应该包含该ip值作为主题备用名称值(类型IPAddress:key = 7)。
  •   
  • 如果您想通过使用DNS作为主机名进行连接;
      您的证书应该包含该DNS名称作为主题备用名称值(类型为DNS:key = 2)或作为CommonName(CN)值。
  •   

答案 1 :(得分:1)

您可能会发现使用SSL调试系统属性有助于调查此问题:

-Djavax.net.debug=ssl

如果打印得太多,你可以过滤一些东西,也许是这样:

-Djavax.net.debug=ssl,trustmanager

输出不一定非常明显,但它应该更详细地告诉您错误的位置。

答案 2 :(得分:0)

如果您手头有服务器证书并且安装了openssl,您可以使用以下内容转储证书的内容:

$ openssl x509 -noout -text -in filename-here.pem

你会看到“CN =”作为主题的一部分,如果它在证书中有altSubjectName扩展名,你会在X509v3扩展名下面看到,作为X509v3主题备用名称,你会看到对于类似DNS的东西:host-name-here。

如果匹配您要连接的主机名,那么只需检查您是通过IP地址连接,还是通过主机名连接,无论您使用何种SSL接口,都要确保它是通过主机名而不是IP地址。< / p>

如果证书中没有匹配的名称(与您要连接的主机名匹配),某些SSL接口将忽略“名称不匹配”。 (我不知道在你的具体情况下如何做到这一点。)

编辑:

尝试通过主机名而不是IP地址进行连接,看看是否存在差异。

如果证书中列出了IP,您将在openssl输出中的X509v3主题备用名称下看到类似IP:xx.xx.xx.xx的内容。

如果未列出IP,请从shell提示符运行nslookup,并比较工作和非工作服务器地址的输出。这可能是工作服务器与主机名匹配的方式(即通过getnetbyaddr)。

编辑2:

您是否尝试过使用主机名(在您的连接字符串中)进行连接并仍然得到相同的错误?使用IP地址通过浏览器连接无关紧要 - 浏览器可能无法使用相同的算法验证主机名。您是否尝试使用连接中的IP地址连接到良好的服务器?另外,请在此处查看:found with quick Google

答案 3 :(得分:0)

问题是WSDL2Java因名称而拒绝了服务器证书。在Java中,用于连接到远程系统的主机名与证书中的公用名非常匹配。它不会基于IP地址反向查找。您必须使用主机名进行连接。

其他回复表明您通过IP地址进行连接。这不是正确的做事方式。 Java将根据它连接的主机名验证证书。

如果使用IP地址进行连接,则可能未在您的环境中设置DNS。解决此问题的最简单方法是将主机名添加到hosts文件中。在Windows中,它位于'C:\ Windows \ System32 \ drivers \ etc \ hosts'。

xx.xx.xx.xx      XXXXXXXXXX.net

这将允许您使用主机名通过WSDL2Java获取WSDL。

<强>替代:

如果仍然无效,还有另一种选择。使用Web浏览器下载.wsdl文件。让WSDL2Java从磁盘上的本地文件而不是Web服务器上创建Java存根。生成的代码将是相同的,但不必通过SSL来获取WSDL。

答案 4 :(得分:0)

可能是您错过了相应的GlobalSign root certificate for Java

# Import a root or intermediate CA certificate to an existing Java keystore
keytool -import -trustcacerts -alias root -file Thawte.crt -keystore keystore.jks

另一种可能性涉及根证书和中间证书的组合。更多来自GlobalSign website

  

“一些Apache和基于Java的   应用程序需要root和   中级证书   捆绑在一个证书中......“