2012-03-06 77 views
4

我正在尝试创建一个使用PKI进行身份验证的java应用程序。我需要能够从Microsoft证书存储(MCS)中检索证书并将其传递给Oracle数据库(11.2)。如何在JDBC中使用Windows密钥库(MCS)?

我使用jdbc:oracle:thin驱动程序进行连接。在谷歌上花了一段时间之后,我已经空了。 我发现不同的属性来改变(文章):

  • 设置属性javax.net.ssl.keyStoreType = "Windows-MY"
  • 设置javax.net.ssl.keyStore = "Windows-MY"
  • javax.net.ssl.keyStore should be set to "None"(如果使用的是定制的KeyManager我不相信,因为将工作当它进入我的自定义KeyManager时,我将已经获得来自连接属性中指定的密钥库的证书)。

当然,所有这些人都声称成功,但没有为我工作。我尝试了所有没有运气的例子。当我使用Oracle钱包时,我能够成功进行身份验证,因此我知道我的证书没问题。如果有人以前做过这个,愿意发布一些很棒的代码。

我知道大多数人在网站上使用Windows keystore,因此正在创建自己的SSLContext,但我无法想象我是唯一一个想用JDBC来做到这一点的人(据我所知,让我提供一个SSLContext)。

这是我认为应该工作的代码,但没有。

DriverManager.registerDriver)new OracleDriver()); 
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=host)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=someName))(SECURITY= (SSL_SERVER_CERT_DN=\"CN=TESTSERVER\")))"; 

java.util.Properties props = new java.util.Properties(); 
props.setProperty("javax.net.ssl.keyStoreType", "Windows-MY"); 
props.setProperty("javax.net.ssl.keyStore", "NONE"); 
props.setProperty("javax.net.ssl.trustStoreType", "Windows-ROOT"); 
props.setProperty("javax.net.ssl.trustStore", "NONE"); 

props.setProperty("oracle.net.ssl_server_dn_match", "true"); 
props.setProperty("oracle.net.authentication_services", "(TCPS)"); 
Connection conn = DriverManager.getConnection(url, props); 

此代码失败,异常:

java.sql.SQLRecoverableException: IOException: The Network Adapter could not establish the connection 
+0

不要将代码格式设置为不是代码的文本。 – EJP 2016-04-22 03:31:47

回答

0

This article应该给你更多的细节。虽然它不使用系统属性,但Windows-MY显然是一种商店类型,它不是基于文件的。因此,javax.net.ssl.keyStoreTypeWindows-MYjavax.net.ssl.keyStore应设置为NONE(大写可能重要),请参阅JSSE Ref Guide (Customization)

javax.net.ssl.keyStore系统属性

注意,值NONE可被指定。如果密钥库不是基于文件的 (例如,它驻留在硬件令牌中),则此设置适用。

如果您的服务器证书不受默认Java信任库的信任,您可能还需要以类似方式配置信任库。

+0

感谢您的快速响应。我已经阅读了两篇文章,但仍然没有任何运气。我用我尝试过的代码和当前错误消息修改了我的原始帖子。 – Ben 2012-03-06 21:56:30

+0

如果驱动程序在JDBC驱动程序实现中没有遵循JSSE Ref Guide中的内容,我不会感到惊讶。如果可以的话(如果它不影响应用程序的其余部分),我会尝试将javax.net.ssl属性设置为全局系统属性,并将这些JDBC属性留空:JDBC驱动程序可能在这种情况下使用默认的'SSLSocketFactory'。 – Bruno 2012-03-06 22:05:15

+0

我试过了,但它仍然无效。我注意到我没有从'System.setProperty(“javax.net.debug”,“SSL”)获得任何调试输出;'所以它在握手过程中似乎没有太大的帮助。 – Ben 2012-03-06 22:39:08