Reputation: 1273
I'm trying to connect to my MySQL instance listening at luther:3306
. I followed these instructions on how to set up SSL for a MySQL instance on Ubuntu and it works great. I can connect to luther:3306
with user ford
no problem from the GUI (MySQL Workbench) when I provide it username, password, SSL key, SSL certificate, and SSL CA.
Now, I'm trying to connect via a Java app and I'm having issues giving Java the correct certificate. Here's the code:
System.setProperty("javax.net.ssl.keyStore","C:/Program Files/Java/jre1.8.0_45/bin/cacerts");
System.setProperty("javax.net.ssl.keyStorePassword","changeit");
System.setProperty("javax.net.ssl.trustStore","C:/Program Files/Java/jre1.8.0_45/bin/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword","changeit");
System.setProperty("javax.net.debug", "SSL");
// Create the DB connection
try {
String connectionUrl = "jdbc:mysql://luther/ford";
Properties dbProps = new Properties();
dbProps.setProperty("user", "ford");
dbProps.setProperty("password", "<password>");
dbProps.setProperty("useSSL", "true");
dbProps.setProperty("requreSSL", "true");
dbConnection = DriverManager.getConnection(connectionUrl, dbProps);
log.info("Connected to DB? " + dbConnection.isValid(5000));
} catch (SQLException e) {
log.fatal("Unable to connect to DB!");
e.printStackTrace();
return;
}
Here's the contents of the CA cert file:
C:\Program Files\Java\jre1.8.0_45\bin>keytool -keystore cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 2 entries
mysqlcacert, Jan 20, 2018, trustedCertEntry,
Certificate fingerprint (SHA1): 71:92:DA:13:02:57:64:49:3D:72:A0:40:1B:B8:55:42:7D:21:0A:CF
mysqlclientcert, Jan 20, 2018, trustedCertEntry,
Certificate fingerprint (SHA1): A1:F5:5A:DB:31:78:D9:3C:F7:D7:C6:28:77:AB:DF:0A:58:CC:EA:A7
It shows that I have my CA cert and my Client cert. Here's the top level exception I get when I run my Java program:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:512)
at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:493)
at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:205)
at org.jsoup.helper.HttpConnection.get(HttpConnection.java:194)
Do I also somehow need to add my CA key or my client key to the keystore?
Upvotes: 1
Views: 3005
Reputation: 197
First, I'm assuming you have already created the keys by following these instructions: https://dev.mysql.com/doc/refman/5.6/en/creating-ssl-files-using-openssl.html
And I'm assuming you've correctly configured the server using these instructions: https://dev.mysql.com/doc/refman/5.6/en/using-encrypted-connections.html
(for those having trouble generating keys, you can use CYGWIN for windows, and download OpenSSL as a package)
Now, for you specifically: There's no need to mess with the CACerts from the java keystore (bad practice). Instead use the following parameters at the end of the java connection string:
https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html
...?useSSL=true&clientCertificateKeyStoreUrl=file://path_to_truststore_file&clientCertificateKeyStorePassword=mypassword
Also, make sure you import the certificates correctly. I myself followed these instructions after much research (I imported them into a separate keystore as recommended by the instructions)
https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-using-ssl.html
This got me connected. I'm running into other issues now, but this should fix your problem.
EDIT: I also had to add the following:
trustCertificateKeyStoreUrl=file://path_to_truststore_file&trustCertificateKeyStorePassword=mypassword
Upvotes: 2