How to use the Windows Keystore (MCS) with JDBC?

2019-06-21 04:31发布

问题:

I am trying to create a java application that uses PKI for authentication. I need to be able to retrieve a certificate from the Microsoft Certificate Store (MCS) and pass it along to an Oracle database (11.2).

I am connecting using the jdbc:oracle:thin driver. After spending quite some time on google I have come up empty. I've found different properties to change (depending on the article):

  • set the property javax.net.ssl.keyStoreType = "Windows-MY"
  • set the javax.net.ssl.keyStore = "Windows-MY"
  • javax.net.ssl.keyStore should be set to "None" (if using a custom KeyManager which I do not believe will work since by the time it gets into my custom KeyManager I will already be given the certs from a keystore specified in the connection properties).

Of course all of these people are claiming success, but nothing has worked for me. I have tried every example I have been able to find all with no luck. I was able to successfully authenticate when I was using Oracle wallets so I know my certificates are fine. If anyone has done this before and is willing to post some code that would be great.

I know most people are using the Windows keystore with a website and therefore are creating their own SSLContext, but I cannot imagine I am the only one who has wanted to do this using JDBC (which as far as I know does not allow me to provide it an SSLContext).

This is the code that I believe should work, but does not.

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);

This code fails with the exception:

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

回答1:

This article should give your more details. Although it doesn't use the system properties, Windows-MY is clearly a store type and it's not file based. Therefore, javax.net.ssl.keyStoreType should be Windows-MY and javax.net.ssl.keyStore should be set to NONE (upper case may matter), see the JSSE Ref Guide (Customization):

javax.net.ssl.keyStore system property

Note that the value NONE may be specified. This setting is appropriate if the keystore is not file-based (for example, it resides in a hardware token).

You may also need to configure your trust store in a similar way if your server certificate isn't trusted by your default Java trust store.