Oracle Database 11g(内置Java 1.6)如何连接仅支持TLS1.1/1.2的HTTPS Web服务?
解决Oracle 11g内置Java 1.6无法连接TLS1.1/1.2服务的问题
我完全懂你的头疼——之前用Java存储过程处理XML签名+HTTPS请求好好的,结果服务商一禁用TLS1.0,Oracle 11g自带的Java 1.6就直接掉链子了。毕竟Java 6默认对TLS1.1和1.2的支持很有限,尤其是数据库内置的JVM通常没跟上后期的安全更新。下面是几个实战验证过的解决方案,你可以根据自己的权限和环境选:
方案1:给Oracle数据库JVM打补丁(最彻底)
Oracle后来针对11g的内置JVM发布了支持TLS1.1/1.2的补丁包,尤其是11.2.0.4版本的相关CPU补丁(比如Patch 21352635,或者对应你数据库版本的最新安全补丁)。操作步骤大概是:
- 先确认你的Oracle 11g具体版本,执行SQL:
SELECT * FROM v$version; - 到Oracle Support下载对应版本的JVM补丁,这个补丁会更新内置JVM的加密库,添加TLS1.1/1.2支持
- 补丁应用完成后,在你的Java存储过程里显式指定使用的TLS协议,比如在创建连接前加:
或者在构建SSL上下文时直接指定协议版本,确保不会 fallback 到TLS1.0System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");
方案2:用第三方加密库扩展TLS支持(无需数据库补丁)
如果没法给数据库打补丁,BouncyCastle这类第三方加密库可以帮Java 6实现TLS1.1/1.2的支持:
- 下载兼容Java 6的BouncyCastle jar包(比如
bcprov-jdk15on-1.70.jar,注意选jdk15on系列,不要用更高版本的) - 用
loadjava命令把jar包加载到数据库的Java类路径中:loadjava -user your_username/your_password@your_db bcprov-jdk15on-1.70.jar - 在你的Java存储过程中,先注册BouncyCastle作为安全提供者:
import java.security.Security; import org.bouncycastle.jce.provider.BouncyCastleProvider; // 在初始化时添加 Security.addProvider(new BouncyCastleProvider()); - 然后基于BouncyCastle创建TLS1.2的SSL上下文,用来构建HTTPS连接:
import javax.net.ssl.SSLContext; SSLContext sslContext = SSLContext.getInstance("TLSv1.2", "BC"); sslContext.init(null, null, null); // 这里可以根据你的证书需求调整密钥管理器 // 用这个sslContext来创建你的HTTPS URLConnection或者HttpClient
方案3:绕过内置JVM,改用外部Java程序(适合无数据库权限的场景)
如果上面两个方案都走不通,你可以把XML签名和HTTPS请求的逻辑抽出来,写成一个独立的Java程序(用Java 8或更高版本,天然支持TLS1.1/1.2),然后通过PL/SQL调用这个外部程序:
- 把Java程序打包成jar包,放在数据库服务器的某个目录下
- 用
DBMS_SCHEDULER创建一个作业,执行这个jar包,或者用UTL_FILE传递XML数据,执行后把响应写回数据库 - 或者通过PL/SQL的外部过程调用(
EXTPROC)来触发这个Java程序
注意事项
- 无论用哪个方案,都要测试签名后的XML在TLS1.1/1.2连接下的完整性,确保证书链和签名验证都正常
- 打补丁前一定要备份数据库,避免操作失误导致问题
- 使用BouncyCastle时,要确保jar包的版本和Java 6兼容,并且已经正确加载到数据库中
内容的提问来源于stack exchange,提问作者Ferguson
相关产品推荐
相关产品推荐

