由于缺少java中的证书而导致Web服务出错(基于XML SOAP)

时间:2012-01-31 19:53:23

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

我需要使用在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) ...

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

2 个答案:

答案 0 :(得分:6)

根据Java版本使用的是,“近期”更新到1.6 JRE / JDK的一个包括全球cacerts的一个显著的变化(受信任的权威签署SSL Certificats,例如威瑞信),包括一些周围的新证书类型。

我建议升级到最新版本的Java以查看是否有效,如果没有,则选项2为...

使用SSLPoke.java您可以找到缺少哪些证书,InstallCert.java安装它们如下;

  1. java InstallCert webserver.domain.com:443
  2. 将生成的“jssecacerts”文件复制到“$ JAVA_HOME \ jre \ lib \ security”文件夹中。
  3. 如果这仍然导致问题,您可以包括sslpoke的输出,示例用法;

    # java SSLPoke webserver.domain.com 443
    Successfully connected
    

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

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

答案 1 :(得分:1)

您可以参考此主题:How to handle invalid SSL certificates with Apache HttpClient?

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

你可以:

  

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

     

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

第一个更容易(在大多数情况下),但你应该在发布之前使用它,否则你很容易接触到#34; Man in中间攻击"。第二(通常)是更好的选择。

这里有一个合成但很好解释的文档,用于代码示例之前描述的那两点: http://ws.apache.org/xmlrpc/ssl.html