Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用SAAJ从密钥库中选择特定的客户端证书_Java_Http_Ssl_Saaj - Fatal编程技术网

Java 使用SAAJ从密钥库中选择特定的客户端证书

Java 使用SAAJ从密钥库中选择特定的客户端证书,java,http,ssl,saaj,Java,Http,Ssl,Saaj,我已经在SAAJ中编写了一个Java客户机,当通过HTTP发送SOAP消息时,该客户机可以成功运行,但是当我试图通过HTTPS将任何SOAP消息发送到需要客户机证书的web服务时,它就不起作用了 在页面底部的以下链接中,它说明了以下内容: 从SAAJ方面来说,您所需要做的就是使用带有HTTPS的URL作为协议。仅当证书成功导入到/jre/lib/security/cacerts中时,此操作才有效;否则JSSE将不允许连接 我按照上面的指示将客户机证书以及相关的根证书导入到Java cacerts

我已经在SAAJ中编写了一个Java客户机,当通过HTTP发送SOAP消息时,该客户机可以成功运行,但是当我试图通过HTTPS将任何SOAP消息发送到需要客户机证书的web服务时,它就不起作用了

在页面底部的以下链接中,它说明了以下内容:

从SAAJ方面来说,您所需要做的就是使用带有HTTPS的URL作为协议。仅当证书成功导入到/jre/lib/security/cacerts中时,此操作才有效;否则JSSE将不允许连接

我按照上面的指示将客户机证书以及相关的根证书导入到Java cacerts中,并运行了该程序,但出现以下错误:

java.net.SocketException: Connection reset
我对流量进行了wireshark跟踪,发现服务器要求Java代码提供客户端证书时,Java代码没有提供客户端证书,因此我有以下问题:

1) 通过只将HTTPS URL传递给soapConnection.call()方法,并将证书导入到我的cacerts文件,这是否足以进行身份验证,即SAAJ是否自动处理?或者,是否需要以上链接中未描述的更多步骤

2) 通过将证书导入my JAVA_HOME中的cacerts文件,JAVA SAAJ客户端在调用soapConnection.call()时是否自动知道要查看此处?或者我需要明确地告诉我的代码要使用什么cacerts文件吗

3) 如果Java SAAJ客户端自动使用my Java_HOME下的cacerts文件,那么它如何知道要使用哪个客户端证书?同样,我是否需要显式地编写代码,或者SAAJ是否自动处理


提前谢谢

我设法解决了这个问题。我使用了以下代码:

static public void doTrustToCertificates() throws Exception 
{

    // Set truststore that contains root / intermediary certs
    System.setProperty("javax.net.ssl.trustStore", "C:\\cert\\trusted.jks");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

    // Set keystore that contains private key
    File pKeyFile = new File("C:\\cert\\privatekey.pfx");
    String pKeyPassword = "Password01";
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    InputStream keyInput = new FileInputStream(pKeyFile);
    keyStore.load(keyInput, pKeyPassword.toCharArray());
    keyInput.close();
    keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

    // Set ssl context with private key and truststore details
    SSLContext sc = SSLContext.getInstance("TLSv1");
    sc.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
    SSLSocketFactory sockFact = sc.getSocketFactory();

    // Add ssl context to https connection
    HttpsURLConnection.setDefaultSSLSocketFactory(sockFact);

}
然后在SAAJ的soapConnection.call()方法之前调用doTrustToCertificates()方法,其工作原理如下:

doTrustToCertificates();
SOAPMessage soapResponse = soapConnection.call(soapMsgXml, ENDPOINT_URL);

我设法弄明白了。我使用了以下代码:

static public void doTrustToCertificates() throws Exception 
{

    // Set truststore that contains root / intermediary certs
    System.setProperty("javax.net.ssl.trustStore", "C:\\cert\\trusted.jks");
    System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

    // Set keystore that contains private key
    File pKeyFile = new File("C:\\cert\\privatekey.pfx");
    String pKeyPassword = "Password01";
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    InputStream keyInput = new FileInputStream(pKeyFile);
    keyStore.load(keyInput, pKeyPassword.toCharArray());
    keyInput.close();
    keyManagerFactory.init(keyStore, pKeyPassword.toCharArray());

    // Set ssl context with private key and truststore details
    SSLContext sc = SSLContext.getInstance("TLSv1");
    sc.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
    SSLSocketFactory sockFact = sc.getSocketFactory();

    // Add ssl context to https connection
    HttpsURLConnection.setDefaultSSLSocketFactory(sockFact);

}
然后在SAAJ的soapConnection.call()方法之前调用doTrustToCertificates()方法,其工作原理如下:

doTrustToCertificates();
SOAPMessage soapResponse = soapConnection.call(soapMsgXml, ENDPOINT_URL);

你没有得到这样的指示。这些说明具有误导性,但它们仅适用于服务器证书是自签名的情况,而完全不适用于客户端需要证书的情况

在这种情况下,需要在客户机的密钥库中创建客户机证书。您可以创建CSR并对其进行签名,然后使用生成密钥对和CSR时使用的相同别名将其导入同一密钥库,或者需要生成自签名证书(yuck),然后将其导出并导入服务器的信任库


您不需要编写任何代码。您只需设置系统属性
javax.net.ssl.keyStore
和朋友来告诉JSSE您的客户机keyStore。

您没有得到这样的指示。这些说明具有误导性,但它们仅适用于服务器证书是自签名的情况,而完全不适用于客户端需要证书的情况

在这种情况下,需要在客户机的密钥库中创建客户机证书。您可以创建CSR并对其进行签名,然后使用生成密钥对和CSR时使用的相同别名将其导入同一密钥库,或者需要生成自签名证书(yuck),然后将其导出并导入服务器的信任库

您不需要编写任何代码。您所需要做的就是设置系统属性
javax.net.ssl.keyStore
,并让朋友告诉JSSE您的客户机密钥库