JMX SSL连接未将javax.net.ssl.trustStore设置为系统属性

时间:2017-03-30 14:05:36

标签: java ssl rmi rpc jmx

我正在尝试使用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调用工作,这意味着客户端套接字实现实际上是由服务器提供的,所以我必须以某种方式将信任存储和密钥存储区传递给服务器对象,但无法找到方法。

1 个答案:

答案 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();
}

}