【问题标题】:Error consuming web service due to lack of certificate in java (XML SOAP based)由于 java 中缺少证书(基于 XML SOAP)而导​​致使用 Web 服务时出错
【发布时间】:2012-02-23 13:14:15
【问题描述】:

我需要使用在 Java 中的 Https 下构建的 Web 服务。 Web 服务客户端是使用 Eclipse 生成的,我使用以下代码来调用它:

ServicioTimbradoPruebasLocator ServicioTimbradoLocator = new ServicioTimbradoPruebasLocator();
                            ServicioTimbradoPruebasSoap ServicioTimbrado = ServicioTimbradoLocator.getServicioTimbradoPruebasSoap();
                            javax.xml.rpc.Stub s =((javax.xml.rpc.Stub)ServicioTimbrado);
                            s._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "XXXXXXXX");
                            s._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "psswd");          
                            String resultado = ServicioTimbrado.generaTimbre(xml.getBytes());
                            System.out.println("resultado: " +resultado);

在这一行 String resultado = ServicioTimbrado.generaTimbre(xml.getBytes()); 我收到以下错误:

AxisFault
     [java]  faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
     [java]  faultSubcode: 
     [java]  faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
     [java]  faultActor: 
     [java]  faultNode: 
     [java]  faultDetail: 
     [java]     {http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
     [java]     at sun.security.ssl.Alerts.getSSLException(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
     [java]     at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
     [java]     at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.processLoop(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.process_record(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
     [java]     at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
     [java]     at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
     [java]     at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
     [java]     at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
     [java]     at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
     [java]     at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
     [java]     at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
     [java]     at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
     [java]     at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2767)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2443)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2366)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:1812)
     [java]     at mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub.generaTimbre(ServicioTimbradoPruebasSoapStub.java:107)
     [java]     at natura.facturacion.general.GuardarFacturaElectronicav2.doPost(GuardarFacturaElectronicav2.java:136) ...

我想知道是否有办法通过网络服务调用发送证书。 有关 wsdl 合约和 java 生成的文件的更多信息可以找到here

【问题讨论】:

  • 在我看来,这更像是证书链中列出的 CA 无法验证,例如它使用了一个 java 一无所知的 CA。
  • 啊...西班牙语的课程和方法...我已经很久没有使用这些了。
  • 为了通信,客户端和 WS 必须共享证书。每个人都有一个密钥库,有一个自己的私钥来解密输入,一个合作伙伴的公钥来加密输出。该路径在与我不记得名称的策略相关的 XML 文件中配置...

标签: java web-services soap certificate webservice-client


【解决方案1】:

根据您使用的 Java 版本,对 1.6 JRE/JDK 的“最近”更新之一包括对全局 CACerts(签署 SSL 证书的受信任机构,例如 Verisign)的重大更改,以包括一些新的证书类型。

我建议升级到最新版本的 Java 看看是否可行,如果不行,选项 2 是...

使用SSLPoke.java可以查出缺少哪些证书,InstallCert.java进行如下安装;

  1. java InstallCert webserver.domain.com:443
  2. 将生成的“jssecacerts”文件复制到“$JAVA_HOME\jre\lib\security”文件夹。

如果这仍然会导致问题,您能否包含 sslpoke 的输出,示例用法;

# java SSLPoke webserver.domain.com 443
Successfully connected

如果所有这些都不起作用,并且您可以获得证书文件 (crt),您可以使用 keytool 命令手动导入该文件(cacerts 是一个将在您的本地工作目录中创建的文件;确保将其移动到JRE/JDK 中的 java 安全文件夹);

keytool -import -trustcacerts -alias AddTrustExternalCARoot -file cetificate.crt -keystore cacerts

【讨论】:

  • 我使用了 InstallCert.java 类,它表明证书已正确添加到我的 javastore。使用此信息生成一个名为 jsseacacerts 的文件。我将此文件复制到 $JAVA_HOME/jre/lib/security 并得到相同的错误。我尝试使用以下命令将我的证书手动导入我的密钥库: $JAVA_HOME/bin/keytool.exe -import -file mycert.cer -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass psswd 我得到了一个 java .ioFileNotFoundException
  • SSLPoke 向我抛出以下错误:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到在 sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) 在 sun.security.ssl.Handshaker.fatalSE(Unknown Source) 在 sun.security.ssl.Alerts.getSSLException(Unknown Source) 请求目标的有效认证路径.security.ssl.Handshaker.fatalSE(Unknown Source) at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)...
  • 可能你的机器上安装了多个Java,InstallCert.java是recommended解决这个问题的方法。您可以尝试使用与您的服务器容器相同的 java 运行时运行 InstallCert 命令吗(我假设它在 Tomcat/JBoss/Glassfish 或类似中?)
  • 在遵循 mkyong.com/webservices/jax-ws/… 的指南后为我工作。它指导如何使用 InstallCert.java。确保通过验证步骤。不过需要重启应用服务器。
【解决方案2】:

你可以参考这个帖子:How to handle invalid SSL certificates with Apache HttpClient?

当然,这里有一个 WSDL SOAP Web 服务,那里有一个 Apache HTTP 客户端,但错误是一样的,你可以用相同的方式(或多种方式)处理它。

你可以:

1 - 强制您的程序接受 ANY SSL 证书

2 - 在您的 JVM 中下载并安装您缺少的 SSL 证书

第一个更容易(在大多数情况下),但你应该在发布之前使用它,否则你很容易受到“中间人攻击”的影响。第二个(通常)是更好的选择。

这里有一个综合但很好解释的文档,对前面描述的两点进行了代码示例: http://ws.apache.org/xmlrpc/ssl.html

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多