Java的JDBC无法连接到使用SSL一个Oracle数据库(Java JDBC unable to

2019-09-28 12:32发布

我已经配置了在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?

请指教,谢谢。

Answer 1:

使用服务或要求您的应用程序中证资源,需要你以某种信任证书颁发者或证书本身。 在这种情况下,我想你必须信任证书本身,因为它是自签名的,而不是由一个著名的CA(已通过您所使用的JRE捆绑信任店内信任)发出的。

为了做到这一点,导出用您的数据库一起使用的证书,并找到一个名为“cacerts的”文件。 该文件的JDK的安装文件夹中存在。 例:

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

最容易做的事情,就是将证书导入到这个文件(你可以使用一些命令来做到这一点,或者如果你是懒惰和我一样-下载KSE,然后单击导入按钮: HTTP://密钥存储资源管理器.org等/ )。 您也可以使用这里提到的属性指定自己信任的店:

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

如果您选择使用自定义信任店,您对cacerts中更多的控制权 - 因为如果你选择升级到较新的JDK安装,该安装将使用与JDK发行:-)的cacerts中。

无论如何。 希望这有助于一点。



Answer 2:

在JVM尝试建立服务器证书的信任链,对任何已知的信任CA。 您可以获取这是由你的Java默认的信任库信任的CA证书,或者你可以提供自己的CA证书由你的JVM(你用来签署自签名证书的) 生成自己的信任库 。 然后,您可以使用命令行参数传递信任库如-Djavax.net.ssl.trustStore=启动应用程序时。

请记住,通过自定义的信任库需要你要么添加它们包含在你的JRE的默认信任库所有CA或你住的事实,没有任何信任链可以建立不通过自己的CA颁发的任何证书

第三个选项是增加自己的CA证书添加到系统的全局信任库导致任何Java应用程序接受来自CA的证书 这是一条捷径,但可能不会在你最感兴趣,如果你需要CA的严格分离。



Answer 3:

我想下面的链接可能会对你有所帮助。

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



Answer 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();
}


文章来源: Java JDBC unable to connect to a Oracle database with SSL