如何使用 setProperty 设置不同的信任库密钥库

How to set different truststore keystore with setProperty

我有一个固定客户端,它使用不同的密钥库(公司一个密钥库)调用固定服务器。在我的 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);

这样,它只在我第一次调用服务器时起作用(示例"Company A")。当我尝试使用另一个密钥库(例如 "Company B")调用服务器时,服务器的响应是:

javax.xml.ws.soap.SOAPFaultException: IDP Rule 'Process Error' aborted processing.

这是因为System.setProperty不是每次都刷新,所以第一次之后客户端总是有"Company A"的keystore。 我也试过将所有经过认证的都放在一个密钥库中,但它不起作用。在这种情况下,我认为所有密码都必须相同。 一些想法?

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();

它return这个错误:

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。 谢谢大家!