为Java 7的TLS添加AES-GCM支持,解决SSL握手失败问题
解决Java 7遗留应用AES-GCM密码套件握手失败问题
一、核心原因说明
Java 7原生TLS栈默认不支持AES-GCM类密码套件,即便你把BouncyCastle(BC)设为首位安全提供者,原生HttpsURLConnection仍会沿用SunJSSE的SSL实现,不会自动切换到BC的SSL逻辑,这就是之前配置后仍握手失败的关键。
二、无代码修改的配置方案
1. 补全BouncyCastle依赖包
别只放bcprov和bcutil,还要下载bcjsse-jdk15to18-175.jar(BC的JSSE扩展包),将三个包一起放入jdk/jre/lib/ext目录。
2. 调整安全提供者顺序
打开jdk/jre/lib/security/java.security文件,把BC的两个提供者移到最前面:
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider security.provider.3=sun.security.provider.Sun # 保留后续原有安全提供者的顺序
3. 强制使用BC的SSLContext(关键步骤)
启动应用时添加以下JVM参数,指定默认SSLContext采用BC的实现:
-Djavax.net.ssl.SSLContext=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
4. 可选:显式指定启用的密码套件
再加一个JVM参数,强制启用服务器支持的AES-GCM套件,按你查到的服务器支持列表调整:
-Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
5. 验证生效状态
重启应用后,开启TLS日志-Djavax.net.debug=ssl:handshake:verbose,查看日志中是否出现BouncyCastleJsseProvider相关内容,以及密码套件列表是否包含目标AES-GCM套件,出现则说明配置生效。
三、配置失效时的极小侵入方案
如果上述配置仍不生效,可在应用启动类中添加一段静态初始化代码(仅执行一次,不改动业务逻辑):
static { Security.addProvider(new BouncyCastleProvider()); Security.addProvider(new BouncyCastleJsseProvider()); try { SSLContext.setDefault(SSLContext.getInstance("TLSv1.2", "BCJSSE")); } catch (NoSuchAlgorithmException | NoSuchProviderException e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Ricky Sixx
相关产品推荐
相关产品推荐

