我已使用钱包和自签名证书配置了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?
请指教,谢谢。
答案 0 :(得分:1)
在您的应用程序中使用需要证书的服务或资源,要求您以某种方式信任证书颁发者或证书本身。在这种情况下,我猜你必须信任证书本身,因为它是自签名的,不是由着名的CA发布的(已经被你正在使用的JRE捆绑的信任存储所信任)。
为此,请导出与数据库一起使用的证书,并找到名为“cacerts”的文件。该文件存在于jdk-installation文件夹中。例如:
/path/to/jdk/jre/lib/security/cacerts
最简单的方法是将证书导入此文件(您可以使用某些命令执行此操作,或者如果您像我一样懒惰 - 下载KSE并单击导入按钮:{{3} })。您还可以使用此处提到的属性指定您自己的信任存储:
如果您选择使用自定义信任存储,则可以更好地控制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)
答案 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();
}