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

导入自签名证书至Java信任库后仍无法信任Oracle数据库连接

问题:Java连接Oracle自签名证书数据库仍报PKIX路径错误

我有一个简单的Java应用,用于连接使用自签名证书的Oracle数据库。已经从Oracle钱包导出证书并导入到Java的cacerts信任库,但运行程序时仍出现以下错误:

javax.net.ssl|ERROR|01|main|2024-09-19 10:35:54.501 CEST|TransportContext.java:352|Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target (
"throwable" : {
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

自签名证书本身没有有效证书路径,但我认为导入信任库后应该被信任,不应该出现这个错误。

Java代码

package org.ibm;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class OracleConnection {

    public static void main(String[] args) throws Exception {

        //Create a custom TrustManager

        VerifyCertificate.verifyCert();
        String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=localhost)(PORT=5500))(CONNECT_DATA=(SERVICE_NAME=your_db))(SECURITY=(SSL_SERVER_CERT_DN=\"\")))";
        Properties props = new Properties();
        props.setProperty("user", "sys");
        props.setProperty("password", "password");

        try (Connection conn = DriverManager.getConnection(url, props)) {
            System.out.println("Connected to the database successfully!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行命令

/home/pat/.sdkman/candidates/java/11.0.23-sem/bin/java -Djavax.net.debug=ssl  -classpath /home/pat/Projects/clients/blm/oracle-ssl/target/classes:/home/pat/.m2/repository/com/oracle/database/jdbc/ojdbc8/19.8.0.0/ojdbc8-19.8.0.0.jar org.ibm.OracleConnection

证书导入命令

keytool -importcert -v -trustcacerts -cacerts -alias myselfsignedcert -file server_cert.pem  -storepass changeit

环境信息

  • JAVA_HOME:/home/pat/.sdkman/candidates/java/current
  • Java版本:
openjdk 11.0.23 2024-04-16
IBM Semeru Runtime Open Edition 11.0.23.0 (build 11.0.23+9)
Eclipse OpenJ9 VM 11.0.23.0 (build openj9-0.44.0, JRE 11 Linux amd64-64-Bit Compressed References 20240522_1104 (JIT enabled, AOT enabled)
OpenJ9   - b0699311c7
OMR      - 254af5a04
JCL      - 3d1045c3ea based on jdk-11.0.23+9)

解决方案

1. 确认证书导入的信任库与运行环境匹配

运行程序使用的JDK是/home/pat/.sdkman/candidates/java/11.0.23-sem,但JAVA_HOME指向的current可能并非该版本。执行以下命令验证:

ls -l /home/pat/.sdkman/candidates/java/current

若路径不匹配,说明证书导入到了错误的cacerts库,需重新导入到运行用JDK的cacerts中,路径一般为/home/pat/.sdkman/candidates/java/11.0.23-sem/lib/security/cacerts。

2. 修正JDBC URL的SSL配置

URL中SSL_SERVER_CERT_DN=""会强制验证服务器证书DN为空,这显然不符合实际,需移除该配置或替换为证书真实DN:

String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=localhost)(PORT=5500))(CONNECT_DATA=(SERVICE_NAME=your_db)))";

3. 排查自定义TrustManager的影响

代码中调用的VerifyCertificate.verifyCert();可能自定义了TrustManager,覆盖了默认信任库配置。检查该类实现:

  • 若未正确加载cacerts证书,需调整逻辑;
  • 若无需自定义验证,直接注释该行代码,让Java使用默认信任库。

4. 验证证书是否成功导入

用keytool检查目标cacerts库中是否存在导入的证书:

keytool -list -v -cacerts -alias myselfsignedcert -storepass changeit

若未找到证书,重新执行导入命令并指定正确的cacerts路径:

keytool -importcert -v -trustcacerts -keystore /home/pat/.sdkman/candidates/java/11.0.23-sem/lib/security/cacerts -alias myselfsignedcert -file server_cert.pem -storepass changeit

5. 利用SSL调试日志确认信任库加载

运行时已启用-Djavax.net.debug=ssl,搜索日志中trustStore相关内容,确认加载的cacerts路径与导入路径一致,同时检查是否识别到目标证书。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:02:30