如何在Axis2 Java客户端中使用自签名证书?

时间:2011-06-25 00:19:23

标签: https client certificate axis2

我使用org.codehaus.mojo axistools-maven-plugin插件版本1.4生成了代码。我正在尝试通过https连接到Web服务。我已将服务器证书安装到jssecacerts中,并将此密钥库复制到/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/文件夹中。所以这意味着我在客户端密钥库中有服务器证书。我还将服务器私钥和证书导入到kestore.ImportKey密钥库中。我想我将不得不使用它作为信任存储。现在,如何在java客户端中将所有这些连接在一起? 我在客户端使用自动生成的存根。我尝试使用以下但不起作用。

System.setProperty("javax.net.ssl.trustStore","certs/keystore.ImportKey");
System.setProperty("javax.net.ssl.trustStorePassword", "importkey"); 

我得到以下异常。

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

证书有效,因为我通过HTTPS客户端为同一主机使用相同的证书。此外,我能够看到成功的curl请求使用相同的证书。实际上,我不知道如何使用自签名服务器证书在https上编写Axis2 soap Java客户端。任何人都可以指出我一步一步的例子。

2 个答案:

答案 0 :(得分:2)

在客户端,您不需要证书私钥来信任服务器。由于您在问题中写道,您导入了keystore.ImportKey中的证书和密钥,我认为它们已作为PrivateKeyEntry导入(您可以使用keytool验证密钥库中的条目类型)。

但是,如果要将证书用作信任锚,则应将证书导入为TrustedCertificateEntry。可以使用keytool

来实现
keytool -importcert -trustcacerts -alias myTrustAnchor -file /path/to/cert.crt -keystore /path/to/keystore

然后,您可以在应用程序中配置信任库:

System.setProperty("javax.net.ssl.trustStore","/path/to/keystore");

答案 1 :(得分:2)

谢谢@Jcs

这就是我解决问题的方法。当我尝试在浏览器中打开Web服务URL时,它要求提供客户端证书。这意味着,因为我已经在jvm中的jssecacert中导入了服务器证书,我的客户端缺少客户端证书。因此,我设置了javax.net.ssl.trustStorejavax.net.ssl.trustStorePassword属性,而不是设置javax.net.ssl.keyStorejavax.net.ssl.keyStorePassword属性,而且工作正常。在私钥和证书导入密钥库之前我错过了。 ImportKey基本上是客户端身份,我从那些说服务器证书的人那里收到了很长时间。这误导了我。所以,如果有人正在寻找它,让我总结一下解决方案。

  1. 下载服务器证书并导入系统路径上的JVM cacerts或jssecacerts。 我使用了this post

  2. 在浏览器中打开Web服务URL,如果要求提供客户端证书,则表示服务器设置为期望来自客户端的证书。如果是自签名证书,则必须已从服务器获得自签名证书。在密钥库中导入它们并在实际调用Web服务之前设置密钥库而不是信任库的系统属性,如下所示。这是因为您已将服务器证书导入客户端信任存储区(cacerts)。

  3. 代码:

    MySoap12Stub stub = (MySoap12Stub) new MyLocator().getMySoap12(new java.net.URL(WSUrl));
    
    System.setProperty("javax.net.ssl.keyStore", "certs/keystoreQA.Importkey");
    System.setProperty("javax.net.ssl.keyStorePassword", "importkey");
    

    此外,在我的情况下,服务器期望将用户令牌和密码设置为SOAP头。这就是我将其设置为SOAP标头的方式:

    ((Stub) stub).setHeader(HeaderHandler.getSecurityHeader(User, password));
    
    public class HeaderHandler {
    
        public static SOAPHeaderElement getSecurityHeader(String user,String password) throws Exception {
            SOAPHeaderElement wsseSecurity = new SOAPHeaderElement(new PrefixedQName(
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
                "Security", "wsse"));
            wsseSecurity.setActor(null);
            wsseSecurity.setMustUnderstand(true);
    
            SOAPElement usernameToken = wsseSecurity.addChildElement("UsernameToken", "wsse");
            usernameToken.setAttribute("xmlns:wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            SOAPElement username = usernameToken.addChildElement("Username", "wsse");
            username.addTextNode(user);
    
            SOAPElement password = usernameToken.addChildElement("Password", "wsse");
            password.setAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
            password.addTextNode(password);
            return wsseSecurity;
        }
    } 
    

    我希望这详细解释如何在使用usertoken和密码通过https的axis2客户端调用Web服务中使用自签名证书和WSSE用户令牌和密码。

    干杯!现在好了。