Categories
amazon-rds java mysql spring-boot ssl

Spring Boot connection to AWS RDS MySQL – SSLHandshakeException: Received fatal alert: unknown_ca

I have a Spring Boot application from which I am trying to connect to a MySQL on AWS RDS.
However I am having issues with the following error:

localhost-startStop-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca

After enabling debug for the ssl handshake, I see that for the CertificateRequest step the Cert Authorities: are empty.
Based on my understanding this is the part where the client (spring boot app) needs to present a cert to the server (mysql db).

  • Certificate Request step – The server will issue a certificate request from the client.
  • The next step would be *** Certificate chain, which is the certificate the client is sending to the server. In this case for me, it is sending the content of keyStore_cert.jks.

What I think the issue so far:
The server (mySQL db) does not know about this certificate (my keyStore_cert.jks) that the client (my app) is sending.
But, I was under the impression that the client certs are not required unless you set REQUIRE X509 for the user.

The questions:

  • Is there something else that I can look in order to find the exact problem?
  • If the above is the issues, how can I fix it? How can I disable client verification?
  • Or how can I keep client verification but have it work?
  • Do I need add anything to the keyStore_cert.jks/trustStore_cert.jks?



These are what my settings and what I have tried.

  • RDS Engine version: 5.7.22
  • mysql-connector-java v8.0.13
  • connection URL: jdbc:mysql://<host>:<port>/<db_name>?useLegacyDatetimeCode=false&verifyServerCertificate=true&useSSL=true&requireSSL=true
  • for the user that I am using I executed the following on the DB:

ALTER USER '<my_db_user>'@'%' require SSL;
GRANT USAGE ON <db_name>.* TO '<my_db_user>'@'%' REQUIRE SSL;

  • Based on the AWS documentation: I imported those certs (root and intermediate) into the trustStore. Doing something: keytool -import -keystore trustStore_cert.jks -storepass <trustStore_password> -alias "awsrds-us-east1" -file rds-ca-2015-us-east-1.pem
  • I use our own keyStore. Nothing was done to the keyStore at this time.
  • application trustStore and keyStore are passed as JVM param like the following:

-Djavax.net.ssl.keyStore=path/keyStore_cert.jks
-Djavax.net.ssl.keyStorePassword=<keyStore_password>
-Djavax.net.ssl.trustStore=path/trustStore_cert.jks
-Djavax.net.ssl.trustStorePassword=<trustStore_password>

  • For the specific user, when I use MySQL Workbench and in the connection setting for Use SSL I specify: If available or Require. It connects with this message:

Host: <host>
Port: <port>
User: <user>
SSL: enabled with DHE-RSA-AES128-SHA

  • However if I specify, Require and Verify CA or Require and Verify Identity it gives this message: SSL connection error: CA certificate is required if ssl-mode is VERIFY_CA or VERIFY_IDENTITY. Which makes sense since i am not specifying anything for the CA file.



Steps for the handshake (will omit some logs.):

*** ClientHello, TLSv1.1 (seems okay)
***
*** ServerHello, TLSv1.1 (seems okay)
***
*** Certificate chain (has the root key)
chain [0] = [
[
Version: V3
Subject: C=US, ST=Washington, L=Seattle, O=Amazon.com, OU=RDS, CN=**<my_rds_name>abcd.us-east-1.rds.amazonaws.com**
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
...
...
chain [1] = [ (has the us-east-1 key)
[
Version: V3
Subject: CN=Amazon RDS us-east-1 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
...
...
***
Found trusted certificate:
[
[
Version: V3
Subject: CN=Amazon RDS us-east-1 CA, OU=Amazon RDS, O="Amazon Web Services, Inc.", L=Seattle, ST=Washington, C=US
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
...
...
*** CertificateRequest (the Authorities are empty)
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
<Empty>
*** ServerHelloDone
matching alias: <my keyStoreAlias>
*** Certificate chain (seems entries from my own key Store)
chain [0] = [
[
Version: V3
Subject: CN=<the CN on my keyStore>, OU=Web Servers, O=Company , C=US
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
***
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1.1 (seems okay)
*** CertificateVerify (seem okay)
*** Finished
verify_data: { 50, 89, 33, 202, 193, 158, 226, 114, 128, 50, 198, 250 }
***