I am trying to securely connect to Amazon RDS using JDK 1.8 and MySQL Connector/J version 5.1.23 and I am confused about the instructions in MySQL Connector/J documentation.
The instructions say to create a truststore in the current directory and import the server's CA certificate. When I run the below command I am asked for a password and I do not know what to enter:
keytool -import -alias mysqlServerCACert -file file_location.pem -keystore truststore
The instructions from Amazon on the other hand point out that certificates are signed by a certificate authority. The SSL certificate includes the DB instance endpoint as the Common Name (CN). The public key is also stored at http://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.
Whilst I understand the concept of SSL/TSL and private/public keys, I am confused how to implement this?
When I run SHOW VARIABLES LIKE 'have_ssl'; command I receive "yes" as a value. When I am connected to the database and run SHOW SESSION STATUS LIKE 'Ssl_version';, I receive no value back.
How do you establish a secure connection from Java to a MySQL database?
Update:
I am using ubuntu and I used the keytool to generate a truststore.jks file in the JRE directory /usr/lib/jvm/java/jre/. I also executed the following command: GRANT USAGE ON db_name.* To 'username'@'address' REQUIRE SSL;
The below code is how I am connecting to the database:
import com.mysql.jdbc.Connection;
public class mainClass{
public static void main(String[] args){
System.setProperty("javax.net.ssl.trustStore", "/usr/lib/jvm/java/jre/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "truststore_password");
final String url = "jdbc:mysql://mysql_rds_enpoint:port/db_name?verifyServerCertificate=true&useSSL=true&requireSSL=true";
final String username = "username";
final String password = "password";
Connection mysqlConnection = null;
mysqlConnection = (Connection) mysqlMethods.connectToMysql(url, username, password);
}
}
The above code produces a Communications link failure message and The last packet successfully received from the server was 24 milliseconds ago. The last packet sent successfully to the server was 24 milliseconds ago. I am able to successfully connect when ?verifyServerCertificate=true&useSSL=true&requireSSL=true is removed from the uri and REQUIRE SSL is removed from the user permissions.
Update 2:
I have taken the code back to basics and when I run the below code:
import java.sql.DriverManager;
import java.sql.SQLException;
class testClass{
public static void main(String[] args){
System.setProperty("javax.net.ssl.trustStore", "/usr/lib/jvm/java/jre/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "truststore_password");
final String url = "jdbc:mysql://mysql_rds_enpoint:port/db_name?verifyServerCertificate=true&useSSL=true&requireSSL=true";
final String username = "username";
final String password = "password";
try {
Object connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I get the following error message:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure