23.3 SSLContext Configuration and Socket Setup

Proper SSLContext configuration is essential for creating secure connections. This section covers configuration options and practical setup patterns.

SSLContext Creation and Initialization

// SSLContext Configuration
public class SSLContextConfiguration {

    // Default SSLContext (uses system trust store)
    public static SSLContext createDefaultSSLContext() throws Exception {
        SSLContext context = SSLContext.getInstance("TLSv1.3");
        context.init(null, null, new SecureRandom());
        return context;
    }

    // SSLContext with custom KeyStore
    public static SSLContext createSSLContextWithKeyStore(
            String keyStorePath, String keyStorePassword,
            String keyPassword) throws Exception {

        // Load key store (contains private keys)
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (InputStream is = new FileInputStream(keyStorePath)) {
            keyStore.load(is, keyStorePassword.toCharArray());
        }

        // Create key manager factory
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(
            KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(keyStore, keyPassword.toCharArray());

        // Create SSL context
        SSLContext context = SSLContext.getInstance("TLSv1.3");
        context.init(kmf.getKeyManagers(), null, new SecureRandom());

        return context;
    }

    // SSLContext with custom TrustStore
    public static SSLContext createSSLContextWithTrustStore(
            String trustStorePath, String trustStorePassword) throws Exception {

        // Load trust store (contains certificates)
        KeyStore trustStore = KeyStore.getInstance("PKCS12");
        try (InputStream is = new FileInputStream(trustStorePath)) {
            trustStore.load(is, trustStorePassword.toCharArray());
        }

        // Create trust manager factory
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
            TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);

        // Create SSL context
        SSLContext context = SSLContext.getInstance("TLSv1.3");
        context.init(null, tmf.getTrustManagers(), new SecureRandom());

        return context;
    }

    // Complete example with both key and trust stores
    public static SSLContext createCompleteSSLContext(
            String keyStorePath, String keyStorePassword, String keyPassword,
            String trustStorePath, String trustStorePassword) throws Exception {

        // Load key store
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (InputStream is = new FileInputStream(keyStorePath)) {
            keyStore.load(is, keyStorePassword.toCharArray());
        }

        // Create key managers
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(
            KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(keyStore, keyPassword.toCharArray());

        // Load trust store
        KeyStore trustStore = KeyStore.getInstance("PKCS12");
        try (InputStream is = new FileInputStream(trustStorePath)) {
            trustStore.load(is, trustStorePassword.toCharArray());
        }

        // Create trust managers
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(
            TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);

        // Create SSL context with both
        SSLContext context = SSLContext.getInstance("TLSv1.3");
        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

        return context;
    }

    // Protocol version selection
    public static SSLContext createSSLContextWithVersion(String protocol) throws Exception {
        SSLContext context = SSLContext.getInstance(protocol);
        context.init(null, null, new SecureRandom());
        return context;
    }

    public static void printAvailableProtocols() throws Exception {
        SSLContext defaultContext = SSLContext.getInstance("DEFAULT");
        SSLEngine engine = defaultContext.createSSLEngine();

        System.out.println("=== AVAILABLE TLS PROTOCOLS ===");
        System.out.println("\nSupported Protocols:");
        for (String protocol : engine.getSupportedProtocols()) {
            System.out.println("  - " + protocol);
        }

        System.out.println("\nEnabled Protocols:");
        for (String protocol : engine.getEnabledProtocols()) {
            System.out.println("  - " + protocol);
        }
    }
}

SSLParameters and Cipher Suite Configuration

// SSL Parameters Configuration
public class SSLParametersConfiguration {

    // Configure SSL parameters for strict security
    public static SSLParameters createStrictSSLParameters() {
        SSLParameters params = new SSLParameters();

        // Only allow TLS 1.3 and TLS 1.2
        params.setProtocols(new String[]{"TLSv1.3", "TLSv1.2"});

        // Recommend strong cipher suites
        params.setCipherSuites(new String[]{
            "TLS_AES_256_GCM_SHA384",           // TLS 1.3
            "TLS_CHACHA20_POLY1305_SHA256",     // TLS 1.3
            "TLS_AES_128_GCM_SHA256",           // TLS 1.3
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",        // TLS 1.2
            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",      // TLS 1.2
            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"   // TLS 1.2
        });

        // Require server authentication
        params.setNeedClientAuth(false);
        params.setWantClientAuth(false);

        // Enable server name indication (SNI)
        params.setServerNames(new java.util.ArrayList<>());

        return params;
    }

    // Cipher suites for different security levels
    public static class CipherSuiteLevels {

        // Modern browsers and clients
        public static String[] getModernCipherSuites() {
            return new String[]{
                "TLS_AES_256_GCM_SHA384",
                "TLS_CHACHA20_POLY1305_SHA256",
                "TLS_AES_128_GCM_SHA256"
            };
        }

        // Compatibility with some older clients
        public static String[] getCompatibleCipherSuites() {
            return new String[]{
                "TLS_AES_256_GCM_SHA384",
                "TLS_CHACHA20_POLY1305_SHA256",
                "TLS_AES_128_GCM_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
            };
        }

        // Maximum compatibility (TLS 1.2 support)
        public static String[] getMaximumCompatibilityCipherSuites() {
            return new String[]{
                "TLS_AES_256_GCM_SHA384",
                "TLS_CHACHA20_POLY1305_SHA256",
                "TLS_AES_128_GCM_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
                "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
                "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
            };
        }
    }

    // Apply SSL parameters to socket
    public static void configureSSLSocket(SSLSocket socket, SSLParameters params) {
        socket.setSSLParameters(params);
    }

    // Apply SSL parameters to engine
    public static void configureSSLEngine(SSLEngine engine, SSLParameters params) {
        engine.setSSLParameters(params);
    }

    // SNI (Server Name Indication)
    public static SSLParameters createSSLParametersWithSNI(String hostname) {
        SSLParameters params = createStrictSSLParameters();

        // Create SNI matcher
        java.util.List<javax.net.ssl.SNIServerName> serverNames = 
            new java.util.ArrayList<>();
        serverNames.add(new javax.net.ssl.SNIHostName(hostname));

        params.setServerNames(serverNames);

        return params;
    }
}

Secure Socket Factory Creation

// Socket Factory Configuration
public class SecureSocketFactoryConfiguration {

    // Create secure socket with manual parameters
    public static void demonstrateSocketConfiguration() throws Exception {
        SSLContext context = SSLContextConfiguration.createDefaultSSLContext();

        // Get socket factory
        javax.net.ssl.SSLSocketFactory factory = context.getSocketFactory();

        // Create socket
        javax.net.ssl.SSLSocket socket = 
            (javax.net.ssl.SSLSocket) factory.createSocket("example.com", 443);

        // Configure parameters
        SSLParameters params = SSLParametersConfiguration.createStrictSSLParameters();
        socket.setSSLParameters(params);

        try {
            // Initiate handshake
            socket.startHandshake();
            System.out.println("Handshake successful");
            System.out.println("Protocol: " + socket.getSession().getProtocol());
            System.out.println("Cipher: " + socket.getSession().getCipherSuite());
        } finally {
            socket.close();
        }
    }

    // SSLEngine for non-blocking I/O
    public static void demonstrateSSLEngine() throws Exception {
        SSLContext context = SSLContextConfiguration.createDefaultSSLContext();

        // Create engine for client-side connection
        SSLEngine engine = context.createSSLEngine("example.com", 443);
        engine.setUseClientMode(true);

        // Configure parameters
        SSLParameters params = SSLParametersConfiguration.createStrictSSLParameters();
        engine.setSSLParameters(params);

        // Engine state
        System.out.println("Need unwrap: " + engine.getSession().isValid());
        System.out.println("Client mode: " + engine.getUseClientMode());
    }
}

HTTP Client SSL Configuration

// HTTP Client SSL Setup
public class HTTPClientSSLConfiguration {

    // Minimal HTTPS client (uses default trust store)
    public static HttpClient createBasicHTTPSClient() {
        return HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .build();
    }

    // HTTPS client with custom SSL context
    public static HttpClient createCustomHTTPSClient(SSLContext sslContext) {
        return HttpClient.newBuilder()
            .sslContext(sslContext)
            .version(HttpClient.Version.HTTP_2)
            .build();
    }

    // HTTPS client with connection timeout
    public static HttpClient createHTTPSClientWithTimeout(
            SSLContext sslContext, 
            java.time.Duration timeout) {
        return HttpClient.newBuilder()
            .sslContext(sslContext)
            .connectTimeout(timeout)
            .version(HttpClient.Version.HTTP_2)
            .build();
    }

    // Complete example with all options
    public static HttpClient createFullFeaturedHTTPSClient(
            String trustStorePath, String trustStorePassword,
            java.time.Duration timeout,
            java.net.Authenticator authenticator) throws Exception {

        // Configure SSL
        SSLContext sslContext = 
            SSLContextConfiguration.createSSLContextWithTrustStore(
                trustStorePath, trustStorePassword);

        return HttpClient.newBuilder()
            .sslContext(sslContext)
            .version(HttpClient.Version.HTTP_2)
            .connectTimeout(timeout)
            .authenticator(authenticator)
            .build();
    }

    // Make HTTPS request
    public static String makeHTTPSRequest(HttpClient client, String url) 
            throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(java.net.URI.create(url))
            .GET()
            .timeout(java.time.Duration.ofSeconds(10))
            .build();

        HttpResponse<String> response = client.send(request, 
            HttpResponse.BodyHandlers.ofString());

        System.out.println("Status: " + response.statusCode());
        System.out.println("Protocol: " + response.version());

        return response.body();
    }
}

Protocol and Cipher Suite Best Practices

// Best Practices Configuration
public class SSLBestPractices {

    public static void printConfigurationCheckklist() {
        System.out.println("=== SSL/TLS CONFIGURATION CHECKLIST ===");

        System.out.println("\n[ ] TLS VERSION");
        System.out.println("    [x] Enable TLS 1.3");
        System.out.println("    [x] Enable TLS 1.2");
        System.out.println("    [ ] Disable TLS 1.1 and below");
        System.out.println("    [ ] Disable SSLv3 and below");

        System.out.println("\n[ ] CIPHER SUITES");
        System.out.println("    [x] Use only authenticated encryption (GCM, ChaCha20-Poly1305)");
        System.out.println("    [ ] Disable CBC mode ciphers if possible");
        System.out.println("    [ ] Disable NULL ciphers");
        System.out.println("    [ ] Disable weak or deprecated ciphers");
        System.out.println("    [x] Prefer forward secrecy (ECDHE, DHE)");

        System.out.println("\n[ ] CERTIFICATE VALIDATION");
        System.out.println("    [x] Verify certificate chain");
        System.out.println("    [x] Check certificate dates");
        System.out.println("    [x] Verify hostname matches certificate");
        System.out.println("    [x] Use system or custom trust store");
        System.out.println("    [ ] Implement certificate pinning if needed");

        System.out.println("\n[ ] KEY MANAGEMENT");
        System.out.println("    [x] Store keys in secure keystore");
        System.out.println("    [x] Use strong keystore passwords");
        System.out.println("    [ ] Restrict keystore file permissions");
        System.out.println("    [ ] Never hardcode passwords");
        System.out.println("    [x] Load passwords from secure configuration");

        System.out.println("\n[ ] SESSION MANAGEMENT");
        System.out.println("    [x] Use secure session identifiers");
        System.out.println("    [x] Enable session caching for performance");
        System.out.println("    [ ] Disable 0-RTT resumption for high-security");
        System.out.println("    [x] Configure appropriate session timeout");

        System.out.println("\n[ ] MONITORING AND LOGGING");
        System.out.println("    [x] Log SSL/TLS handshake events");
        System.out.println("    [x] Monitor certificate expiration");
        System.out.println("    [x] Alert on validation failures");
        System.out.println("    [ ] Track cipher suite usage");
    }

    // Configuration factory for different scenarios
    public static class ConfigurationTemplates {

        // Development environment (less strict)
        public static SSLContext developmentSSLContext() throws Exception {
            return SSLContextConfiguration.createDefaultSSLContext();
        }

        // Production environment (strict)
        public static SSLContext productionSSLContext(
                String keyStorePath, String keyStorePassword, String keyPassword,
                String trustStorePath, String trustStorePassword) throws Exception {
            return SSLContextConfiguration.createCompleteSSLContext(
                keyStorePath, keyStorePassword, keyPassword,
                trustStorePath, trustStorePassword);
        }

        // High-security environment (with additional checks)
        public static SSLContext highSecuritySSLContext(
                String keyStorePath, String keyStorePassword, String keyPassword,
                String trustStorePath, String trustStorePassword,
                String pinnedPublicKeyHash) throws Exception {

            SSLContext base = SSLContextConfiguration.createCompleteSSLContext(
                keyStorePath, keyStorePassword, keyPassword,
                trustStorePath, trustStorePassword);

            // Additional configuration for pinning, OCSP, etc.
            // would be done here

            return base;
        }
    }
}

Troubleshooting SSL Configuration

// SSL/TLS Troubleshooting
public class SSLTroubleshooting {

    // Enable detailed SSL debugging
    public static void enableSSLDebugging() {
        System.setProperty("javax.net.debug", "ssl:handshake:verbose");
    }

    // Diagnostic information
    public static void printSSLDiagnostics() throws Exception {
        System.out.println("=== SSL/TLS DIAGNOSTICS ===");

        // Supported protocols
        SSLContext context = SSLContext.getInstance("DEFAULT");
        SSLEngine engine = context.createSSLEngine();

        System.out.println("\nSupported Protocols:");
        for (String p : engine.getSupportedProtocols()) {
            System.out.println("  - " + p);
        }

        System.out.println("\nEnabled Protocols:");
        for (String p : engine.getEnabledProtocols()) {
            System.out.println("  - " + p);
        }

        System.out.println("\nSupported Cipher Suites:");
        for (String c : engine.getSupportedCipherSuites()) {
            System.out.println("  - " + c);
        }

        System.out.println("\nEnabled Cipher Suites:");
        for (String c : engine.getEnabledCipherSuites()) {
            System.out.println("  - " + c);
        }

        // System properties
        System.out.println("\nSSL System Properties:");
        System.out.println("  javax.net.ssl.keyStore: " + 
            System.getProperty("javax.net.ssl.keyStore"));
        System.out.println("  javax.net.ssl.trustStore: " + 
            System.getProperty("javax.net.ssl.trustStore"));
        System.out.println("  javax.net.ssl.keyStoreType: " + 
            System.getProperty("javax.net.ssl.keyStoreType"));
        System.out.println("  javax.net.ssl.trustStoreType: " + 
            System.getProperty("javax.net.ssl.trustStoreType"));
    }

    // Common configuration errors
    public static void printCommonConfigurationErrors() {
        System.out.println("=== COMMON CONFIGURATION ERRORS ===");

        System.out.println("\n1. WRONG PROTOCOL");
        System.out.println("   Problem: SSLContext.getInstance(\"SSL\")");
        System.out.println("   Error: SSL is deprecated");
        System.out.println("   Solution: Use \"TLSv1.3\" or \"TLSv1.2\"");

        System.out.println("\n2. UNINITIALIZED CONTEXT");
        System.out.println("   Problem: Using context without init()");
        System.out.println("   Error: Null pointer or default context");
        System.out.println("   Solution: Always call context.init()");

        System.out.println("\n3. WRONG KEYSTORE TYPE");
        System.out.println("   Problem: KeyStore.getInstance(\"JKS\") for PKCS12 file");
        System.out.println("   Error: KeyStore format error");
        System.out.println("   Solution: Match keystore type to file format");

        System.out.println("\n4. PASSWORD ISSUES");
        System.out.println("   Problem: Wrong keystore or key password");
        System.out.println("   Error: Keystore integrity check failed");
        System.out.println("   Solution: Verify passwords match keystore");

        System.out.println("\n5. MISSING TRUST ANCHOR");
        System.out.println("   Problem: Self-signed cert not in trust store");
        System.out.println("   Error: sun.security.validator.ValidatorException");
        System.out.println("   Solution: Import certificate into trust store");
    }
}

Best Practices Summary

  • Always use TLSv1.3 or TLSv1.2: Never allow older protocols.
  • Choose strong cipher suites: Prefer authenticated encryption.
  • Enable forward secrecy: Use ECDHE or DHE.
  • Validate certificates properly: Chain, dates, and hostname.
  • Secure keystore files: Restrict permissions and use strong passwords.
  • Never disable certificate validation: Exception to development only.
  • Use custom trust managers sparingly: Only when absolutely necessary.
  • Monitor certificate expiration: Set alerts for renewals.
  • Test SSL configuration: Verify with online testing tools.
  • Enable security debugging: During development and troubleshooting.