我正在尝试使用SSL保护我的JMX连接,因为我能够通过设置java系统属性来指定java信任存储和密钥存储,这里是代码片段:
HashMap<String,Object> env = new HashMap<String,Object>();
// check if jmx ssl config file exists
if(checkIfFileExists(JMX_SSL_CONFIG)) {
String keyStore = null;
String keyStorePassword = null;
String trustStore = null;
String trustStorePassword = null;
Properties prop = new Properties();
InputStream input = null;
input = new FileInputStream(JMX_SSL_CONFIG);
prop.load(input);
keyStore = prop.getProperty("javax.net.ssl.keyStore");
keyStorePassword = prop.getProperty("javax.net.ssl.keyStorePassword");
trustStore = prop.getProperty("javax.net.ssl.trustStore");
trustStorePassword = prop.getProperty("javax.net.ssl.trustStorePassword");
System.setProperty("javax.net.ssl.trustStore", trustStore);
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
System.setProperty("javax.net.ssl.keyStore", keyStore);
System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
}
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
问题是我不想通过设置系统属性来设置信任存储/密钥存储,因为它在我的系统中打破了其他一些东西。我想以某种方式通过SslRMIClientSocketFactory或SslRMIServerSocketFactory传递它们。我知道JMX连接通过RMI调用工作,这意味着客户端套接字实现实际上是由服务器提供的,所以我必须以某种方式将信任存储和密钥存储区传递给服务器对象,但无法找到方法。
答案 0 :(得分:-1)
您可以在自定义ssl工厂中传递信任库(和密钥库)。您必须稍微扩展代码以添加密钥库。
在这个例子中,Spring用于从类路径加载信任库,但是如果没有Spring,它也可以以不同方式加载。
public class CustomSslSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;
static String password;
static String truststore;
public CustomSslSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
if (truststore == null || password == null) {
return null;
}
ClassPathResource res = new ClassPathResource(truststore);
List<X509Certificate> certs = new ArrayList<>();
try (InputStream is = res.getInputStream()) {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(is, password.toCharArray());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
certs.add((X509Certificate) ks.getCertificate(alias));
}
} catch (Exception e) {
throw new RuntimeException("Truststore invalid or not readable!");
}
return certs.toArray(new java.security.cert.X509Certificate[certs.size()]);
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
//checkit
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
//checkit
}
} };
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
delegate = sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Socket createSocket() throws IOException {
return this.delegate.createSocket();
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return this.delegate.createSocket(host, port);
}
@Override
public Socket createSocket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException {
return this.delegate.createSocket(host, port, localAddress, localPort);
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return this.delegate.createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
return this.delegate.createSocket(host, port, localAddress, localPort);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return this.delegate.createSocket(socket, host, port, autoClose);
}
@Override
public String[] getDefaultCipherSuites() {
return this.delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return this.delegate.getSupportedCipherSuites();
}
public static SocketFactory getDefault() {
return new CustomSslSocketFactory();
}
}