nicholas79171
nicholas79171

Reputation: 1273

Can't Connect to MySQL via SSL (Unable to find valid certification path to requested target)

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

Answers (1)

Robert Allurent
Robert Allurent

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

Related Questions