【问题标题】:NoHostAvailable when trying to connect to SSL enabled Cassandra尝试连接到启用 SSL 的 Cassandra 时 NoHostAvailable
【发布时间】:2017-12-26 22:02:19
【问题描述】:

我正在尝试使用 Spring 连接到启用 SSL 的 Cassandra。我已收到密钥库和信任库文件及其各自的密码。使用 DevCenter 工具,我可以使用这些文件和凭据连接到远程数据库。 但是,当我尝试使用 java 连接时,我不断收到以下异常:

客户端身份验证似乎没有正确通过。

忽略不支持的密码套件:TLSv1.1 的 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
        忽略不支持的密码套件:TLSv1.1 的 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
        %% 没有缓存的客户端会话
        *** 客户端您好,TLSv1.2
        RandomCookie: GMT: 1500600803 字节 = { 210, 125, 166, 7, 213, 206, 126, 108, 110, 254, 207, 58, 13, 147, 17, 116, 100, 203, 214, 85, 221, 233、167、43、110、114、95、111}
        会话 ID:{}
        密码套件:[TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA、TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA、TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA、SSL_DHE_RSA_WITH_3DES_EDE_CBC _SHA、SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA、TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        压缩方法:{0}
        扩展elliptic_curves,曲线名称:{secp256r1,sect163k1,sect163r2,secp192r1,secp224r1,sect233k1,sect233r1,sect283k1,sect283r1,secp384r1,sect409k1,sect409r1,secp521r1,sect571k1,sect571r1,secp160k1,secp160r1,secp160r2,sect163r1,secp192k1,sect193r1,sect193r2 , secp224k1, sect239k1, secp256k1}
        扩展 ec_point_formats,格式:[未压缩]
        扩展签名算法、签名算法:SHA512withECDSA、SHA512withRSA、SHA384withECDSA、SHA384withRSA、SHA256withECDSA、SHA256withRSA、SHA224withECDSA、SHA224withRSA、SHA1withECDSA、SHA1withRSA、SHA1withDSA
        ***
        cluster1-nio-worker-0,写入:TLSv1.2 握手,长度 = 193
        cluster1-nio-worker-0,调用 closeOutbound()
        cluster1-nio-worker-0,closeOutboundInternal()
        cluster1-nio-worker-0,发送 TLSv1.2 ALERT:警告,描述 = close_notify
        cluster1-nio-worker-0,写入:TLSv1.2 警报,长度 = 2
        cluster1-nio-worker-0,调用 closeInbound()
        cluster1-nio-worker-0,致命错误:80:入站在收到对等方的 close_notify 之前关闭:可能的截断攻击?
        javax.net.ssl.SSLException:入站在收到对等方的 close_notify 之前关闭:可能的截断攻击?
        cluster1-nio-worker-0,发送 TLSv1.2 警报:致命,描述 = internal_error
        cluster1-nio-worker-0,异常发送警报:java.io.IOException:写入端已关闭。
        线程“主”com.datastax.driver.core.exceptions.NoHostAvailableException 中的异常:所有主机都尝试查询失败(尝试:/172.18.34.226:9042(com.datastax.driver.core.exceptions.TransportException:[ /172.18.34.226:9042] 频道已关闭))
        在 com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:233)
        在 com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79)
        在 com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1483)
        在 com.datastax.driver.core.Cluster.init(Cluster.java:159)
        在 com.datastax.driver.core.SessionManager.initAsync(SessionManager.java:78)
        在 com.datastax.driver.core.SessionManager.executeAsync(SessionManager.java:139)
        在 com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:68)
        在 com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:43)
        在 ClientToNode.execute(ClientToNode.java:49)
        在 ClientToNode.main(ClientToNode.java:27)
        在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        在 java.lang.reflect.Method.invoke(Method.java:498)
        在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

使用以下代码:

private Cluster getCluster(final String trustStoreLocation, final String trustStorePassword, final String keyStoreLoc, final String keyStorePass,final String host) throws UnrecoverableKeyException {
        final Cluster cluster;
        SSLContext sslcontext = null;

        try {
            final InputStream trustStoreStream = ClientToNode.class.getResourceAsStream(trustStoreLocation);
            final KeyStore keystore = KeyStore.getInstance("jks");
            final char[] trustChars = trustStorePassword.toCharArray();
            keystore.load(trustStoreStream, trustChars);

            final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keystore);
            final TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            final InputStream keyStoreStream = ClientToNode.class.getResourceAsStream(keyStoreLoc);
            final KeyStore keyStore = KeyStore.getInstance("jks");
            final char[] pwdKeyStore = keyStorePass.toCharArray();
            keyStore.load(keyStoreStream, pwdKeyStore);

            final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, keyStorePass.toCharArray());
            final KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();


            sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(keyManagers, trustManagers, new SecureRandom());
        } catch (Exception e) {
            e.printStackTrace();
        }

        //String[] ciphers = {"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"};
        JdkSSLOptions sslOptions = JdkSSLOptions.builder()
                                                .withSSLContext(sslcontext)
                                                //.withCipherSuites(ciphers)
                                                .build();

        cluster = Cluster.builder()
                         .addContactPoint(host)
                         .withSSL(sslOptions)
                         .build();
        return cluster;
    }

【问题讨论】:

    标签: java cassandra spring-data


    【解决方案1】:

    进行了以下更改以解决此问题:

    1. 连接到启用 SSL 的 Cassandra 的先决条件是安装 Java Cryptography Extension (JCE),将 UnlimitedJCEPolicy contect 提取到 JRE。欲了解更多信息,请访问Connecting DevCenter to SSL-enabled Cassandra

    IMP:要将 DevCenter 连接到启用 SSL 的 Cassandra,我们需要替换 JRE 下存在的 JCE 文件,该文件位于 C:\Program Files\Java\jre1.8.0_91\lib\security。 p>

    要使用 Java 代码连接到启用 SSL 的 Cassandra,我们需要将 JCE 文件放在 JDK 下的 JRE 中,即 C:\Program Files\Java\jdk1.8.0_91\jre\lib\security强>

    1. 在构建集群时未添加凭据:

      cluster = Cluster.builder() .addContactPoint(host) .withSSL(sslOptions) .withCredentials("dbuser", "password") .build();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 2020-12-23
      • 2016-12-08
      • 2016-06-14
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多