java - 不将javax.net.ssl.trustStore设置为系统属性的JMX SSL连接

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

最佳答案

您可以在自定义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();
}


}

关于java - 不将javax.net.ssl.trustStore设置为系统属性的JMX SSL连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43120258/

相关文章:

java - 检查 Firestore 查询是否为空

java - 无法在 Java 代码中引用类

java - RMI - 谁调用了该方法

回调中的 Java RMI 超时

java - 总和为 A 的 N 个整数的不同组数

java - 无法正确验证java方法中的平衡括号解析

ssl - 关于使用 Ticket 恢复 TLS session

python - 如何使用 python M2Crypto 提取 RSA 公共(public)指数

java - tomcat中服务器的客户端/证书身份验证

java - 为什么java RMI不能通过引用获取返回值