Java 如何使用setProperty设置不同的truststore密钥库

Java 如何使用setProperty设置不同的truststore密钥库,java,ssl,keystore,Java,Ssl,Keystore,我有一个固定客户机,它使用不同的密钥库(公司有一个密钥库)调用固定服务器。在java中,每次我设置trustStore和keyStore系统属性时,如下所示: ..reading path and password from database.. System.setProperty("javax.net.ssl.trustStore", ..path..); System.setProperty("javax.net.ssl.trustStorePassword", ..password..)

我有一个固定客户机,它使用不同的密钥库(公司有一个密钥库)调用固定服务器。在java中,每次我设置trustStore和keyStore系统属性时,如下所示:

..reading path and password from database..
System.setProperty("javax.net.ssl.trustStore", ..path..);
System.setProperty("javax.net.ssl.trustStorePassword", ..password..);
System.setProperty("javax.net.ssl.keyStore", ..path..);
System.setProperty("javax.net.ssl.keyStorePassword", ..password);
这样,它只在我第一次调用服务器时才起作用(例如“companya”)。当我尝试使用另一个密钥库(例如“Company B”)调用服务器时,服务器的响应是:

javax.xml.ws.soap.SOAPFaultException: IDP Rule 'Process Error' aborted processing.
这是因为System.setProperty不会每次刷新,所以在第一次之后,客户端始终拥有“Company A”的密钥库。 我还尝试将所有经过认证的密钥放在一个密钥库中,但它不起作用。在这种情况下,我认为所有密码都必须相同。 一些想法

Misantrops响应后更新

我尝试使用以下代码:

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

InputStream trustStore1 = new FileInputStream(path1);
keyStore.load(trustStore1, password1.toCharArray());
trustStore1.close();

InputStream trustStore2 = new FileInputStream(path2);
keyStore.load(trustStore2, password2.toCharArray());
trustStore2.close();

InputStream trustStore3 = new FileInputStream(path3);
keyStore.load(trustStore3, password3.toCharArray());
trustStore3.close();

TrustManagerFactory tmf =  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
SSLSocketFactory sslFactory = ctx.getSocketFactory();
它返回以下错误:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.] with root cause

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

最后我找到了解决办法:

    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

    String path1 = ..absolute path of keystore..
    path1 = path1.replaceAll("%20", " ");
    InputStream trustStore1 = new FileInputStream(path1);
    keyStore.load(trustStore1, new String(..keystore password..).toCharArray());
    trustStore1.close();

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    keyManagerFactory.init(keyStore, new String(..keystore password..).toCharArray());

    TrustManagerFactory tmf =  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    SSLContext ctx = SSLContext.getInstance("SSL");
    ctx.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
只需使用对象SSLContext的方法“init”,就可以在运行时更改密钥库。此函数的参数是KeyManager和TrustManager,与脚本中一样初始化。这样,就可以模拟System.setProperty。
谢谢大家

这回答了你的问题吗?嗨,米桑托普,谢谢你。它不起作用,我在主题中加入了错误或者这个(1)将所有(远程)证书放在一个文件中应该适用于truststore;你没有给出你做了什么或你认为失败了什么的任何细节,所以我帮不了你。但是,单个文件通常不适用于密钥库,因此,如果您确实需要单独的密钥库,那么也需要单独的信任库(2)对于单独的信任库,以及对于单独的密钥库(未发布),您必须使用单独的
密钥库
对象。不能将多个文件加载到一个
密钥库
对象中;每个
load
都会覆盖内容,只剩下最后一个加载的内容。我通过使用SSLContext“init”方法并传递KeyManager和TrustManager找到了解决方案。谢谢大家!