Scylla Documentation Logo Documentation
  • Server
    • Scylla Open Source
    • Scylla Enterprise
    • Scylla Alternator
  • Cloud
    • Scylla Cloud
    • Scylla Cloud Docs
  • Tools
    • Scylla Manager
    • Scylla Monitoring Stack
    • Scylla Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
Download
Menu

Caution

You're viewing documentation for a previous version of Scylla Java Driver. Switch to the latest stable version.

Scylla Java Driver Manual Core driver SSL

SSL¶

Quick overview¶

Secure the traffic between the driver and Cassandra.

  • advanced.ssl-engine-factory in the configuration; defaults to none, also available: config-based, or write your own.

  • or programmatically: CqlSession.builder().withSslEngineFactory() or CqlSession.builder().withSslContext().


There are two aspects to SSL:

  • client-to-node encryption, where the traffic is encrypted, and the client verifies the identity of the Cassandra nodes it connects to;

  • optionally, client certificate authentication, where Cassandra nodes also verify the identity of the client.

This section describes the driver-side configuration; it assumes that you’ve already configured SSL in Cassandra:

  • the Cassandra documentation covers a basic approach with self-signed certificates, which is fine for development and tests.

  • this blog post details a more advanced solution based on a Certificate Authority (CA).

Preparing the certificates¶

Client truststore¶

This is required for client-to-node encryption.

If you’re using self-signed certificates, you need to export the public part of each node’s certificate from that node’s keystore:

keytool -export -alias cassandra -file cassandranode0.cer -keystore .keystore

Then add all public certificates to the client truststore:

keytool -import -v -trustcacerts -alias <cassandra_node0> -file cassandranode0.cer -keystore client.truststore
keytool -import -v -trustcacerts -alias <cassandra_node1> -file cassandranode1.cer -keystore client.truststore
...

If you’re using a Certificate Authority, the client truststore only needs to contain the CA’s certificate:

keytool -import -v -trustcacerts -alias CARoot -file ca.cer -keystore client.truststore

Client keystore¶

If you also intend to use client certificate authentication, generate the public and private key pair for the client:

keytool -genkey -keyalg RSA -alias client -keystore client.keystore

If you’re using self-signed certificates, extract the public part of the client certificate, and import it in the truststore of each Cassandra node:

keytool -export -alias client -file client.cer -keystore client.keystore
keytool -import -v -trustcacerts -alias client -file client.cer -keystore server.truststore

If you’re using a CA, sign the client certificate with it (see the blog post linked at the top of this page). Then the nodes’ truststores only need to contain the CA’s certificate (which should already be the case if you’ve followed the steps for inter-node encryption).

Driver configuration¶

By default, the driver’s SSL support is based on the JDK’s built-in implementation: JSSE (Java Secure Socket Extension),.

To enable it, you need to define an engine factory in the configuration.

JSSE, property-based¶

datastax-java-driver {
  advanced.ssl-engine-factory {
    class = DefaultSslEngineFactory
    
    # This property is optional. If it is not present, the driver won't explicitly enable cipher
    # suites on the engine, which according to the JDK documentations results in "a minimum quality
    # of service".
    // cipher-suites = [ "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA" ]

    # Whether or not to require validation that the hostname of the server certificate's common
    # name matches the hostname of the server being connected to. If not set, defaults to true.
    // hostname-validation = true

    # The locations and passwords used to access truststore and keystore contents.
    # These properties are optional. If either truststore-path or keystore-path are specified,
    # the driver builds an SSLContext from these files.  If neither option is specified, the
    # default SSLContext is used, which is based on system property configuration.
    // truststore-path = /path/to/client.truststore
    // truststore-password = password123
    // keystore-path = /path/to/client.keystore
    // keystore-password = password123
  }
}

Alternatively to storing keystore and truststore information in your configuration, you can instead use JSSE system properties:

-Djavax.net.ssl.trustStore=/path/to/client.truststore
-Djavax.net.ssl.trustStorePassword=password123
# If you're using client authentication:
-Djavax.net.ssl.keyStore=/path/to/client.keystore
-Djavax.net.ssl.keyStorePassword=password123

JSSE, custom factory¶

If you need more control than what system properties allow, you need to write your own engine factory. If you just need specific configuration on the SSLEngine, you can extend the default factory and override newSslEngine. For example, here is how you would configure custom AlgorithmConstraints:

public class CustomSslEngineFactory extends DefaultSslEngineFactory {

  public CustomSslEngineFactory(DriverContext context) {
    super(context);
  }

  @Override
  public SSLEngine newSslEngine(SocketAddress remoteEndpoint) {
    SSLEngine engine = super.newSslEngine(remoteEndpoint);
    SSLParameters parameters = engine.getSSLParameters();
    parameters.setAlgorithmConstraints(...);
    engine.setSSLParameters(parameters);
    return engine;
  }
}

Then declare your custom implementation in the configuration:

datastax-java-driver {
  advanced.ssl-engine-factory {
    class = com.mycompany.CustomSslEngineFactory
  }
}

JSSE, programmatic¶

You can also provide a factory instance programmatically. This will take precedence over the configuration:

SslEngineFactory yourFactory = ...
CqlSession session = CqlSession.builder()
    .withSslEngineFactory(yourFactory)
    .build();

If you are reusing code that configures SSL programmatically, you can use ProgrammaticSslEngineFactory as an easy way to wrap that into a factory instance:

SSLContext sslContext = ...
String[] cipherSuites = ...
boolean requireHostNameValidation = ...
CqlSession session =
    CqlSession.builder()
        .withSslEngineFactory(
            new ProgrammaticSslEngineFactory(
                sslContext, cipherSuites, requireHostNameValidation))
        .build();

Finally, there is a convenient shortcut on the session builder if you just need to pass an SSLContext:

SSLContext sslContext = ...
CqlSession session = CqlSession.builder()
    .withSslContext(sslContext)
    .build();

Netty-tcnative¶

Netty supports native integration with OpenSSL / boringssl. The driver does not provide this out of the box, but with a bit of custom development it is fairly easy to add. See SslHandlerFactory in the developer docs.

PREVIOUS
Speculative query execution
NEXT
Statements
  • 4.12.0.x
    • 4.13.0.x
    • 4.12.0.x
    • 4.11.1.x
    • 4.10.0.x
    • 4.7.2.x
    • 3.11.2.x
    • 3.11.0.x
    • 3.10.2.x
    • 3.7.2.x
  • Java Driver for Scylla and Apache Cassandra®
  • API Documentation
  • Manual
    • API conventions
    • Case sensitivity
    • Core driver
      • Address resolution
      • Asynchronous programming
      • Authentication
      • Bill of Materials (BOM)
      • Compression
      • Configuration
        • Reference configuration
      • Control connection
      • Custom codecs
      • Detachable types
      • Query idempotence
      • Integration
      • Load balancing
      • Logging
      • Metadata
        • Node metadata
        • Schema metadata
        • Token metadata
      • Metrics
      • Native protocol
      • Non-blocking programming
      • Paging
      • Performance
      • Connection pooling
      • Query timestamps
      • Reactive Style Programming
      • Reconnection
      • Request tracker
      • Retries
      • Using the shaded JAR
      • Speculative query execution
      • SSL
      • Statements
        • Batch statements
        • Per-query keyspace
        • Prepared statements
        • Simple statements
      • Temporal types
      • Request throttling
      • Query tracing
      • Tuples
      • User-defined types
    • Developer docs
      • Administrative tasks
      • Common infrastructure
        • Concurrency
        • Driver context
        • Event bus
      • Native protocol layer
      • Netty pipeline
      • Request execution
    • Mapper
      • Integration
        • Kotlin
        • Lombok
        • Java 14 Records
        • Scala
      • DAOs
        • Custom result types
        • Delete methods
        • GetEntity methods
        • Increment methods
        • Insert methods
        • Null saving strategy
        • Query methods
        • Query provider methods
        • Select methods
        • SetEntity methods
        • Statement attributes
        • Update methods
      • Entities
      • Mapper interface
    • OSGi
    • Query builder
      • Conditions
      • DELETE
      • Idempotence in the query builder
      • INSERT
      • Relations
      • Schema builder
        • Aggregate
        • Function
        • Index
        • Keyspace
        • Materialized View
        • Table
        • Type
      • SELECT
      • Terms
      • TRUNCATE
      • UPDATE
  • Upgrade guide
  • Frequently asked questions
  • Changelog
  • Create an issue
  • Edit this page

On this page

  • SSL
    • Quick overview
    • Preparing the certificates
      • Client truststore
      • Client keystore
    • Driver configuration
      • JSSE, property-based
      • JSSE, custom factory
      • JSSE, programmatic
      • Netty-tcnative
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon
© 2022, ScyllaDB. All rights reserved.
Last updated on 25 May 2022.
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.2.2