簡體   English   中英

嘗試連接到啟用SSL的Cassandra時NoHostAvailable

[英]NoHostAvailable when trying to connect to SSL enabled Cassandra

我正在嘗試使用Spring連接到啟用SSL的Cassandra。 我已經收到密鑰庫和信任庫文件以及它們各自的密碼。 使用DevCenter工具,我可以使用這些文件和憑據連接到遠程數據庫。 但是,當我嘗試使用java進行連接時,仍然收到以下異常:

似乎客戶端驗證未正確通過。

Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
        Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1.1
        %% No cached client session
        *** ClientHello, TLSv1.2
        RandomCookie:  GMT: 1500600803 bytes = { 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 }
        Session ID:  {}
        Cipher Suites: [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]
        Compression Methods:  { 0 }
        Extension elliptic_curves, curve names: {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}
        Extension ec_point_formats, formats: [uncompressed]
        Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA224withECDSA, SHA224withRSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
        ***
        cluster1-nio-worker-0, WRITE: TLSv1.2 Handshake, length = 193
        cluster1-nio-worker-0, called closeOutbound()
        cluster1-nio-worker-0, closeOutboundInternal()
        cluster1-nio-worker-0, SEND TLSv1.2 ALERT:  warning, description = close_notify
        cluster1-nio-worker-0, WRITE: TLSv1.2 Alert, length = 2
        cluster1-nio-worker-0, called closeInbound()
        cluster1-nio-worker-0, fatal error: 80: Inbound closed before receiving peer's close_notify: possible truncation attack?
        javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
        cluster1-nio-worker-0, SEND TLSv1.2 ALERT:  fatal, description = internal_error
        cluster1-nio-worker-0, Exception sending alert: java.io.IOException: writer side was already closed.
        Exception in thread "main" com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /172.18.34.226:9042 (com.datastax.driver.core.exceptions.TransportException: [/172.18.34.226:9042] Channel has been closed))
        at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:233)
        at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79)
        at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1483)
        at com.datastax.driver.core.Cluster.init(Cluster.java:159)
        at com.datastax.driver.core.SessionManager.initAsync(SessionManager.java:78)
        at com.datastax.driver.core.SessionManager.executeAsync(SessionManager.java:139)
        at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:68)
        at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:43)
        at ClientToNode.execute(ClientToNode.java:49)
        at ClientToNode.main(ClientToNode.java:27)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at 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;
    }

進行了以下更改以解決此問題:

  1. 連接到啟用SSL的Cassandra的前提條件是安裝Java密碼擴展(JCE),將UnlimitedJCEPolicy提取為JRE。 有關更多信息,請訪問將DevCenter連接到啟用SSL的Cassandra

IMP:要將DevCenter連接到啟用SSL的Cassandra,我們需要替換JRE下存在的JCE文件,位於C:\\ Program Files \\ Java \\ jre1.8.0_91 \\ lib \\ security

要使用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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM