# Advanced TLS configuration

This guide covers advanced TLS configuration including cipher suite selection, naming conventions, and troubleshooting.

::: basic tls setup
For basic TLS configuration, see [Connect with TLS](https://aerospike.com/docs/develop/client/sdk/connect#connect-with-tls).
:::

## Cipher suite selection

Cipher suites determine the encryption algorithms used for TLS connections. Choose suites based on your security requirements and performance needs.

### Recommended cipher suites

| Security Level | Cipher Suites | Use Case |
| --- | --- | --- |
| High | `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256` | Financial, healthcare |
| Standard | `TLS_AES_128_GCM_SHA256` | General production |
| Compatible | Include `TLS_ECDHE_RSA_*` | Legacy client support |

## OpenSSL vs IANA naming

Aerospike server uses OpenSSL naming, while Java clients use IANA (RFC) naming. Use this mapping table:

| IANA Name (Java) | OpenSSL Name (Server) | TLS Version |
| --- | --- | --- |
| `TLS_AES_256_GCM_SHA384` | `TLS_AES_256_GCM_SHA384` | 1.3 |
| `TLS_AES_128_GCM_SHA256` | `TLS_AES_128_GCM_SHA256` | 1.3 |
| `TLS_CHACHA20_POLY1305_SHA256` | `TLS_CHACHA20_POLY1305_SHA256` | 1.3 |
| `TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384` | `ECDHE-RSA-AES256-GCM-SHA384` | 1.2 |
| `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` | `ECDHE-RSA-AES128-GCM-SHA256` | 1.2 |
| `TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384` | `ECDHE-ECDSA-AES256-GCM-SHA384` | 1.2 |
| `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256` | `ECDHE-ECDSA-AES128-GCM-SHA256` | 1.2 |

::: note
TLS 1.3 cipher names are identical between IANA and OpenSSL. The difference only affects TLS 1.2 ciphers.
:::

## Server-side cipher configuration

Configure allowed ciphers in `aerospike.conf`:

```plaintext
network {

    tls tls-name {

        cert-file /etc/aerospike/certs/server.crt

        key-file /etc/aerospike/certs/server.key

        ca-file /etc/aerospike/certs/ca.crt

        # TLS 1.3 ciphers (recommended)

        cipher-suite TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256

        # Or TLS 1.2 ciphers (OpenSSL naming)

        # cipher-suite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

        # Minimum protocol version

        protocols TLSv1.2 TLSv1.3

    }

}
```

## Client-side cipher configuration

-   [Java](#tab-panel-3050)
-   [Python](#tab-panel-3051)

```java
import com.aerospike.client.sdk.Cluster;

import com.aerospike.client.sdk.ClusterDefinition;

import javax.net.ssl.SSLContext;

// Create SSL context with specific ciphers

SSLContext sslContext = SSLContext.getInstance("TLSv1.3");

sslContext.init(keyManagers, trustManagers, null);

// Configure cluster with TLS

try (Cluster cluster = new ClusterDefinition("secure.aerospike.example.com", 4333)

    .withTlsConfigOf()

        .tlsName("aerospike-server")

        .customSslContext(sslContext)

        .protocols("TLSv1.3", "TLSv1.2")

        .ciphers(

            "TLS_AES_256_GCM_SHA384",

            "TLS_AES_128_GCM_SHA256",

            "TLS_CHACHA20_POLY1305_SHA256"

        )

        .done()

    .connect()) {

    // Use cluster / session here

}
```

### Using a custom SSLContext

```java
import com.aerospike.client.sdk.Cluster;

import com.aerospike.client.sdk.ClusterDefinition;

import javax.net.ssl.SSLContext;

import javax.net.ssl.TrustManagerFactory;

import java.io.FileInputStream;

import java.io.InputStream;

import java.security.KeyStore;

KeyStore trustStore = KeyStore.getInstance("PKCS12");

try (InputStream in = new FileInputStream("/path/to/truststore.p12")) {

    trustStore.load(in, "password".toCharArray());

}

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

tmf.init(trustStore);

SSLContext customSslContext = SSLContext.getInstance("TLSv1.3");

customSslContext.init(null, tmf.getTrustManagers(), null);

try (Cluster cluster = new ClusterDefinition("secure.aerospike.example.com", 4333)

    .withTlsConfigOf()

        .tlsName("aerospike-server")

        .customSslContext(customSslContext)

        .done()

    .connect()) {

    // Use cluster / session here

}
```

```python
from aerospike_sdk import ClusterDefinition

cluster = await (

    ClusterDefinition("secure.aerospike.example.com", 4333)

    .with_tls_config_of()

    .tls_name("aerospike-server")

    .ca_file("/path/to/ca.crt")

    .protocols("TLSv1.3", "TLSv1.2")

    .ciphers(

)

            "TLS_AES_256_GCM_SHA384",

            "TLS_AES_128_GCM_SHA256",

            "TLS_CHACHA20_POLY1305_SHA256",

        (

            )

            .done()

            .connect()

        )
```

## Troubleshooting TLS handshake issues

### Common error messages

| Error | Likely Cause | Solution |
| --- | --- | --- |
| `handshake_failure` | No common cipher suite | Check cipher configuration on both sides |
| `certificate_unknown` | CA not trusted | Verify CA certificate path |
| `certificate_expired` | Cert past validity | Renew certificate |
| `bad_certificate` | Cert/key mismatch | Regenerate cert with correct key |

### Debugging with Java

Enable TLS debugging to see handshake details:

Terminal window

```bash
# Full TLS debugging

java -Djavax.net.debug=ssl:handshake -jar your-app.jar

# Only handshake messages

java -Djavax.net.debug=ssl:handshake:verbose -jar your-app.jar

# Only cipher negotiation

java -Djavax.net.debug=ssl:handshake:ciphersuites -jar your-app.jar
```

Sample debug output for cipher negotiation:

```plaintext
javax.net.ssl|DEBUG|...ClientHello, TLSv1.3

...

Cipher Suites: [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, ...]

...

javax.net.ssl|DEBUG|...ServerHello, TLSv1.3

...

Cipher Suite: TLS_AES_256_GCM_SHA384
```

### Debugging with Python

```python
import logging

# Enable SSL debugging

logging.basicConfig(level=logging.DEBUG)

logging.getLogger('ssl').setLevel(logging.DEBUG)

# Or use OpenSSL directly

import subprocess

result = subprocess.run([

    'openssl', 's_client',

    '-connect', 'secure.aerospike.example.com:4333',

    '-tls1_3',

    '-CAfile', '/path/to/ca.crt'

], capture_output=True, text=True)

print(result.stdout)
```

### Verify server cipher support

Use OpenSSL to check which ciphers the server accepts:

Terminal window

```bash
# Check TLS 1.3 ciphers

openssl s_client -connect server:4333 -tls1_3 -ciphersuites TLS_AES_256_GCM_SHA384

# Check TLS 1.2 ciphers

openssl s_client -connect server:4333 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384

# List all supported ciphers

nmap --script ssl-enum-ciphers -p 4333 server
```

### Certificate chain verification

Verify your certificate chain is complete:

Terminal window

```bash
# Check certificate

openssl x509 -in server.crt -text -noout

# Verify chain

openssl verify -CAfile ca.crt server.crt

# Check key matches certificate

openssl x509 -noout -modulus -in server.crt | openssl md5

openssl rsa -noout -modulus -in server.key | openssl md5

# Both should output the same hash
```

## Performance considerations

### Cipher performance

| Cipher | Relative Performance | Notes |
| --- | --- | --- |
| `TLS_AES_128_GCM_SHA256` | Fastest | Hardware AES-NI |
| `TLS_AES_256_GCM_SHA384` | Fast | Hardware AES-NI |
| `TLS_CHACHA20_POLY1305_SHA256` | Fast | Better on ARM without AES-NI |
| `ECDHE-RSA-AES256-GCM-SHA384` | Moderate | TLS 1.2, more CPU for key exchange |

### Recommendations

1.  **Use TLS 1.3** when possible—faster handshakes, better security
2.  **Prefer AES-GCM** on x86 with AES-NI support
3.  **Use ChaCha20** on ARM or older CPUs without AES-NI
4.  **Enable session resumption** to reduce handshake overhead

-   [Java](#tab-panel-3048)
-   [Python](#tab-panel-3049)

```java
// Enable session caching (default in most JVMs)

SSLContext sslContext = SSLContext.getInstance("TLSv1.3");

SSLSessionContext sessionContext = sslContext.getClientSessionContext();

sessionContext.setSessionCacheSize(100);

sessionContext.setSessionTimeout(3600);  // 1 hour
```

```python
# Session caching is automatic in Python's ssl module

# But you can tune the context

ssl_context.options |= ssl.OP_NO_TICKET  # Disable tickets if not needed
```

## Next steps

Connect with TLS

Basic TLS setup guide.

[TLS Connection →](https://aerospike.com/docs/develop/client/sdk/connect#connect-with-tls)

Common Issues

Troubleshoot connection problems.

[Common Issues →](https://aerospike.com/docs/develop/client/sdk/reference/common-issues)