【问题标题】:Java JDBC unable to connect to a Oracle database with SSLJava JDBC 无法使用 SSL 连接到 Oracle 数据库
【发布时间】:2016-12-22 11:20:35
【问题描述】:

我已将 Oracle 11g 数据库服务器配置为使用钱包和自签名证书使用 SSL。 使用本地客户端(sqlplus)对其进行了测试,并且没有任何问题。 现在我正在尝试使用 Java JDBC 连接数据库。 目前我收到一个错误:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target

这是我的代码:

public static void main(String[] args)
{
    Connection connection = null;

    String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=VDB)))";

    Properties props = new Properties();
    props.setProperty("user", "dbuser");
    props.setProperty("password", "dbpass");
    props.setProperty("oracle.net.ssl_cipher_suites","(SSL_RSA_WITH_3DES_EDE_CBC_SHA)");

    /* Load the database driver */
    try
    {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        connection = DriverManager.getConnection(url,props);
        if (connection != null) {
            System.out.println("You made it, take control your database now!");
        } else {
            System.out.println("Failed to make connection!");
        }
    }
    catch (SQLException ex) {
       ex.printStackTrace();
    }
}

我做了更多研究,发现如果钱包配置为'auto_login',我可以尝试以下:

   Connection connection = null;

   String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=VDB)))";

    Properties props = new Properties();
    props.setProperty("user", "dbuser");
    props.setProperty("password", "dbpass");
    props.setProperty("javax.net.ssl.trustStore", "C:\\oracle\\wallet\\cwallet.sso");
    props.setProperty("javax.net.ssl.trustStoreType","SSO");

    /* Load the database driver */
    try
    {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        connection = DriverManager.getConnection(url,props);
        if (connection != null) {
            System.out.println("You made it, take control your database now!");
        } else {
            System.out.println("Failed to make connection!");
        }
    }
    catch (SQLException ex) {
    ex.printStackTrace();
}

在这种情况下,我得到:

java.security.NoSuchAlgorithmException: SSO KeyStore not available

我添加了 3 个罐子:oraclepki.jar、osdt_cert.jar、osdt_core.jar 尝试运行最后一个版本的代码,得到异常:

java.lang.ClassNotFoundException: com.phaos.crypto.AuthenticationException

也许我应该指定钱包位置?就像我在 tnsnames.ora 文件中所做的那样?还是指定证书CN?

请指教,谢谢。

【问题讨论】:

    标签: java oracle ssl jdbc


    【解决方案1】:

    在您的应用程序中使用需要证书的服务或资源,要求您以某种方式信任证书颁发者或证书本身。在这种情况下,我想您将不得不信任证书本身,因为它是自签名的,而不是由知名 CA 颁发的(已经被与您正在使用的 JRE 捆绑在一起的信任库信任)。

    为此,请导出与数据库一起使用的证书并找到一个名为“cacerts”的文件。该文件存在于您的 jdk 安装文件夹中。示例:

    /path/to/jdk/jre/lib/security/cacerts
    

    最简单的做法是将证书导入此文件(您可以使用一些命令来执行此操作,或者如果您像我一样懒惰 - 下载 KSE 并单击导入按钮:http://keystore-explorer.org/) .您还可以使用此处提到的属性指定您自己的信任库:

    https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html

    如果您选择使用自定义信任库,您可以更好地控制 cacerts - 就像您选择更新到较新的 jdk 安装一样,该安装将使用 jdk 发布的 cacerts :-)。

    无论如何。希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      JVM 尝试建立一个服务器证书对任何已知受信任 CA 的信任链。您可以从受 Java 默认 TrustStore 信任的 CA 获取证书,也可以通过 generating your own TrustStore 向 JVM 提供您自己的 CA 证书(用于签署自签名证书的证书)。然后,您将通过 TrustStore,例如启动应用程序时使用命令行参数-Djavax.net.ssl.trustStore=

      请记住,传递自定义 TrustStore 要求您添加包含在 JRE 的默认 TrustStore 中的所有 CA,或者您接受这样一个事实,即无法为不是由您自己的 CA 颁发的任何证书建立信任链。

      第三种选择是将您自己的 CA 证书添加到系统的全局 TrustStore,这会导致任何 Java 应用程序接受来自您的 CA 的证书。这是一条捷径,但如果您需要严格分离 CA,则可能不符合您的最佳利益。

      【讨论】:

      • 我应该只为服务器证书生成 TrustStore 吗?或客户端和服务器证书?另外,除了ojdbc6.jar,我还需要另一个jar?
      • 如果您的客户端需要使用客户端证书进行身份验证,您可以将其放入 KeyStore(这是同一种文件,但用途不同)。在您的 TrustStore 中,您只需要为服务器证书建立信任链所需的证书(这就像服务器向您的客户端提供的身份证)。因此,在您的情况下,建立所述信任链所需的证书是用于签署服务器证书的 CA 证书。
      • 我的服务器证书是自签名的,所以我只需要将它导入到 TrustStore 中?
      • 您至少有两个证书在使用:您的自签名服务器证书和另一个用于签署服务器证书的证书。您需要将后一个导入到 TrustStore。
      • 我没有使用任何证书来签署服务器证书,这是我使用的命令: orapki wallet add -wallet "C:\oracle\wallet" -pwd WalletPasswd123 -dn "CN=DBSERVER" -keysize 1024 -self_signed -sign_alg sha256 -validity 3650
      【解决方案3】:

      我认为下面的链接可能对你有帮助。

      http://docs.oracle.com/cd/B19306_01/java.102/b14355/sslthin.htm#BABHFBJD

      【讨论】:

      • 我添加了以下 props.setProperty("oracle.net.wallet_location", "(SOURCE=(METHOD=file)(METHOD_DATA=(DIRECTORY=c:\\oracle\\wallet) ))");现在我得到:“java.sql.SQLException:找不到 PKI 类。要使用 'connect /' 功能,oraclepki.jar 必须在类路径中:java.lang.NoClassDefFoundError: oracle/s ecurity/pki/OracleWallet”我可能需要另一个罐子吗?
      • 其实我还没有实现这种功能。我刚在谷歌上找到一篇文章,我读了它。所以,我想它可能会对你有所帮助。所以,我给你。
      【解决方案4】:

      找到了解决方案,因为我使用的是 SSO 需要同时指定密钥库和信任库。

              Connection connection = null;
          String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=NNVSDB)))";
      
          Properties props = new Properties();
          props.setProperty("user", "dbuser");
          props.setProperty("password", "dbpass");
      
          //Single sign on
          props.setProperty("javax.net.ssl.trustStore", "C:\\oracle\\wallet\\cwallet.sso");
          props.setProperty("javax.net.ssl.trustStoreType","SSO");
          props.setProperty("javax.net.ssl.keyStore","C:\\oracle\\wallet\\cwallet.sso");
          props.setProperty("javax.net.ssl.keyStoreType","SSO");
          props.setProperty("oracle.net.authentication_services","(TCPS)");
      
          /* Load the database driver */
          try
          {
              Security.addProvider(new oracle.security.pki.OraclePKIProvider());
              DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
              connection = DriverManager.getConnection(url,props);
              if (connection != null) {
                  System.out.println("You made it, take control your database now!");
              } else {
                  System.out.println("Failed to make connection!");
              }
          }
          catch (SQLException ex) {
          ex.printStackTrace();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 2018-11-30
        • 2018-09-13
        • 2021-06-27
        • 1970-01-01
        • 2022-12-11
        相关资源
        最近更新 更多