Java JDBC无法使用SSL

时间:2016-12-22 11:20:35

标签: java oracle ssl jdbc

我已使用钱包和自签名证书配置了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个Jars:oraclepki.jar,osdt_cert.jar,osdt_core.jar 尝试运行代码的最后一个版本,获得异常:

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

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

请指教,谢谢。

4 个答案:

答案 0 :(得分:1)

在您的应用程序中使用需要证书的服务或资源,要求您以某种方式信任证书颁发者或证书本身。在这种情况下,我猜你必须信任证书本身,因为它是自签名的,不是由着名的CA发布的(已经被你正在使用的JRE捆绑的信任存储所信任)。

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

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

最简单的方法是将证书导入此文件(您可以使用某些命令执行此操作,或者如果您像我一样懒惰 - 下载KSE并单击导入按钮:{{3} })。您还可以使用此处提到的属性指定您自己的信任存储:

http://keystore-explorer.org/

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

反正。希望它有所帮助。

答案 1 :(得分:0)

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

请记住,传递自定义TrustStore要求您添加JRE默认TrustStore中包含的所有CA,或者您可以确定不能为您自己的CA颁发的任何证书建立信任链。

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

答案 2 :(得分:0)

我认为以下链接可能对您有所帮助。

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

答案 3 :(得分:0)

找到解决方案,因为我使用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();
}