我有一个固定的客户端,它使用不同的密钥库(公司的一个密钥库)来调用固定服务器。在我的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”的密钥库。我还尝试将所有经过认证的密钥放入一个密钥库中,但是它不起作用。在这种情况下,我认为所有密码都必须相同。有什么想法吗?
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。谢谢大家!