You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Java 11启用特定密码套件TLS_RSA_WITH_AES_256_CBC_SHA256

问题描述

Java应用启动时遭遇SSL握手失败,排查发现服务器要求使用特定密码套件TLS_RSA_WITH_AES_256_CBC_SHA256,但客户端Hello消息中未包含该套件,导致无法连接服务器。需要了解如何在客户端启用该套件,同时作为SSL/TLS新手,需掌握相关解决问题的知识。

环境信息

  • Java版本:11.0.22
  • JRE供应商:Red Hat, Inc.
  • JVM版本:11.0.22+7-LTS

java -version输出

openjdk version "11.0.22" 2024-01-16 LTS
OpenJDK Runtime Environment (Red_Hat-11.0.22.0.7-1) (build 11.0.22+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-11.0.22.0.7-1) (build 11.0.22+7-LTS, mixed mode, sharing)

java.security配置项

jdk.tls.disabledAlgorithms

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

jdk.disabled.namedCurves

jdk.disabled.namedCurves = secp112r1, secp112r2, secp128r1, secp128r2, \
    secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
    secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
    sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
    sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
    sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, \
    X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, \
    X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, \
    X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3, brainpoolP256r1, \
    brainpoolP320r1, brainpoolP384r1, brainpoolP512r1

crypto.policy

crypto.policy=unlimited

测试代码及输出

用于打印客户端支持的密码套件和协议的代码:

try {
    SSLContext sslContext = SSLContext.getDefault();
    SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

    System.out.println("Supported Ciphers:");
    for (String cipher: sslSocketFactory.getSupportedCipherSuites()) {
        System.out.println(cipher);
    }

    System.out.println("\nSupported Protocols:");
    for (String protocol: sslContext.getSupportedSSLParameters().getProtocols()) {
        System.out.println(protocol);
    }
} catch (Exception e) {
    e.printStackTrace();
}

输出结果中未包含TLS_RSA_WITH_AES_256_CBC_SHA256,但此前相同Java版本的另一个安装中该套件存在。


解决方案

1. 确认密码套件未被间接禁用

当前jdk.tls.disabledAlgorithms配置未直接禁用TLS_RSA_WITH_AES_256_CBC_SHA256,且该套件的组成部分(RSA密钥交换、AES-256-CBC加密、SHA256摘要)均未被禁用,排除配置禁用因素。

2. 手动配置SSLContext添加目标套件

默认SSLContext可能未包含该套件,需手动创建SSLContext并指定包含目标套件的列表,确保客户端Hello消息携带该套件:

import javax.net.ssl.*;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

public class CustomSSLSetup {
    public static void main(String[] args) throws Exception {
        // 获取默认支持的套件列表
        SSLContext defaultCtx = SSLContext.getDefault();
        String[] defaultCiphers = defaultCtx.getSocketFactory().getSupportedCipherSuites();
        
        // 构建包含目标套件的列表(优先添加目标套件)
        List<String> cipherList = new ArrayList<>();
        cipherList.add("TLS_RSA_WITH_AES_256_CBC_SHA256");
        for (String cipher : defaultCiphers) {
            // 排除不安全的NULL/匿名套件
            if (!cipher.contains("NULL") && !cipher.contains("anon")) {
                cipherList.add(cipher);
            }
        }
        
        // 创建自定义SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, new SecureRandom());
        
        // 设置密码套件到SSL参数
        SSLParameters sslParams = sslContext.getSupportedSSLParameters();
        sslParams.setCipherSuites(cipherList.toArray(new String[0]));
        
        // 应用到Socket(如果是HTTP客户端,需将此SSLContext配置到客户端实例)
        SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("your-server-host", 443);
        socket.setSSLParameters(sslParams);
        
        // 验证握手
        socket.startHandshake();
        System.out.println("握手成功,协商套件:" + socket.getSession().getCipherSuite());
    }
}

如果使用Apache HttpClient、OkHttp等HTTP客户端,需将自定义SSLContext注入客户端的配置中,确保请求使用指定的套件列表。

3. 排查Java发行版差异

同为Java 11,不同发行版(如Red Hat OpenJDK vs Adoptium OpenJDK)的默认套件支持可能存在差异:

  • 对比两个Java安装的java.security文件,检查是否有其他隐藏配置差异
  • 升级到当前发行版的最新补丁版本,确认是否修复了套件支持问题

SSL/TLS新手必备知识
  • 密码套件结构:套件命名遵循密钥交换算法_加密算法_摘要算法规则,比如TLS_RSA_WITH_AES_256_CBC_SHA256代表RSA密钥交换、AES-256-CBC加密、SHA256摘要,了解结构可快速判断套件是否被禁用或支持。
  • 核心配置文件:JAVA_HOME/jre/lib/security/java.security是控制Java SSL行为的核心,重点关注jdk.tls.disabledAlgorithms(禁用的算法/套件)、crypto.policy(需设为unlimited才能支持256位加密)。
  • SSL握手流程:握手时客户端发送支持的套件列表,服务器选择双方共有的套件,若服务器要求的套件不在客户端列表中则握手失败。
  • 排查工具:用openssl s_client -connect server:port -cipher TLS_RSA_WITH_AES_256_CBC_SHA256验证服务器是否真的支持该套件;用Wireshark抓包可直接查看客户端Hello中的套件列表。

内容的提问来源于stack exchange,提问作者Mauricio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:44:58