如何使用setProperty设置不同的信任库密钥库 [英] How to set different truststore keystore with setProperty
问题描述
我有一个固定客户端,该客户端使用不同的密钥库(公司的一个密钥库)调用固定服务器.在我的Java中,每次我这样设置trustStore和keyStore系统属性时:
I have a fixed client that call a fixed server using different keystores (one keystore for company). In my java, every time I set trustStore and keyStore system properties like this:
..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")调用服务器时,服务器的响应是:
In this way, it works only the first time that I call the server (example "Company A"). When I try to call the server with another keystore (example "Company B"), the response from server is:
javax.xml.ws.soap.SOAPFaultException: IDP Rule 'Process Error' aborted processing.
这是因为System.setProperty不会每次都刷新,因此,在第一次启动之后,客户端始终具有"Company A"的密钥库. 我还尝试将所有经过认证的密钥放入一个密钥库中,但这是行不通的.在这种情况下,我认为所有密码都必须相同. 有想法吗?
This because System.setProperty not refreshing each time, so after the first time the client have always the keystore of "Company A". I tried also to put all the certified inside one keystore, but it doesn't work. In this case all the passwords have to be the same I think. Some ideas?
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
推荐答案
最后我找到了解决方法:
Finally I found the solution:
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. 谢谢大家!
It's possibile to change at runtime the keystore simply using the method "init" of object SSLContext. The parameters of this function are KeyManager and TrustManager, initialized like in the script. So, in this way it's possible to simulate System.setProperty. Thank you to everyone!
这篇关于如何使用setProperty设置不同的信任库密钥库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!