gpt4 book ai didi

java - Spring Boot 连接到 AWS RDS MySQL - SSLHandshakeException : Received fatal alert: unknown_ca

转载 作者:行者123 更新时间:2023-11-29 01:48:54 40 4
gpt4 key购买 nike

我有一个 Spring Boot 应用程序,我试图从中连接到 AWS RDS 上的 MySQL。但是我遇到以下错误:

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

为 ssl 握手启用调试后,我看到了 CertificateRequestCert Authorities:是空的。根据我的理解,这是客户端(spring boot 应用程序)需要向 服务器(mysql 数据库)提供证书的部分。

  • Certificate Request步骤 - 服务器将发出来自客户端的证书请求。
  • 下一步是 *** Certificate chain ,这是客户端发送到服务器的证书。在这种情况下,我发送的是 keyStore_cert.jks 的内容。 .

到目前为止我认为的问题:服务器(mySQL 数据库)不知道客户端(我的应用程序)正在发送的证书(我的 keyStore_cert.jks)。但是,我的印象是除非您设置 REQUIRE X509,否则不需要客户端证书。为用户。

问题:

  • 是否还有其他我可以查看的内容以找到确切的问题?
  • 如果是上述问题,我该如何解决?如何禁用客户端验证?
  • 或者我怎样才能保持客户验证并让它发挥作用?
  • 我需要在 keyStore_cert.jks 中添加任何内容吗?/trustStore_cert.jks


这些是我的设置和我尝试过的。

  • RDS 引擎版本:5.7.22
  • mysql-connector-java v8.0.13
  • 连接网址:jdbc:mysql://<host>:<port>/<db_name>?useLegacyDatetimeCode=false&verifyServerCertificate=true&useSSL=true&requireSSL=true
  • 对于我正在使用的用户,我在数据库上执行了以下操作:
ALTER USER '<my_db_user>'@'%' require SSL;
GRANT USAGE ON <db_name>.* TO '<my_db_user>'@'%' REQUIRE SSL;
  • 基于 AWS documentation :我将这些证书(根证书和中间证书)导入到 trustStore 中。做某事:keytool -import -keystore trustStore_cert.jks -storepass <trustStore_password> -alias "awsrds-us-east1" -file rds-ca-2015-us-east-1.pem
  • 我使用我们自己的 keystore 。此时没有对 keyStore 进行任何操作。
  • 应用程序 trustStore 和 keyStore 作为 JVM 参数传递,如下所示:
-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>
  • 对于特定用户,当我使用 MySQL Workbench 时,在使用 SSL 的连接设置中,我指定:如果可用需要。它与此消息相关联:
Host: <host>
Port: <port>
User: <user>
SSL: enabled with DHE-RSA-AES128-SHA
  • 但是,如果我指定需要并验证 CA需要并验证身份,它会给出此消息:SSL connection error: CA certificate is required if ssl-mode is VERIFY_CA or VERIFY_IDENTITY .这是有道理的,因为我没有为 CA 文件指定任何内容。


握手的步骤(将省略一些日志。):

*** 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 }
***

最佳答案

在与 AWS RDS Support 合作后,我得到了问题原因和解决方法的解释。

澄清一下,这个问题主要只有在您将自己的 keystore 作为 JVM 参数的一部分传递时才会出现。像这样:

 -Djavax.net.ssl.keyStore=path/keyStore_cert.jks
-Djavax.net.ssl.keyStorePassword=<keyStore_password>

RDS 是一项托管服务,它们(目前)无法将特定客户端证书加载到服务器中。这意味着他们无法通过数据库配置级别的特定证书。如果您要建立自己的 MY SQL 服务器,通常这是可能的。在该服务器的配置文件中,您可以指定客户端/服务器证书。因此,RDS无法验证客户端提供的证书。

如果您在 SSL 握手期间传递具有 key 对条目(作为 JVM 参数或其他方式)的 keystore ,则客户端身份验证步骤将失败。这是数据库中的预期行为。 RDS 无法限制自己在初始连接时为客户端验证(或不验证)客户端字段中加载的文件。因此,如果传递了 keystore ,服务器将尝试将证书 key 与现有 CA 文件进行匹配,如果不匹配,则不允许连接。

解决方案是要么根本不传递 keystore ,要么传递一个空白 keystore (没有 key 对且只有受信任的证书条目或只有空白的 keystore )。

  1. 如果您选择不传递 keystore ,则不要指定这些属性 -Djavax.net.ssl.keyStore= & -Djavax.net.ssl.keyStorePassword= .并像这样构造数据库连接 URL:
    -Ddb_jdbc_url=jdbc:mysql://<host>:<port>/<db_name>?useLegacyDatetimeCode=false&verifyServerCertificate=true&useSSL=true&requireSSL=true .您仍然需要提供信任库。请参阅底部了解更多信息。

  2. 传递一个黑色的keystore或者(或者传递keystore字段中的trust store)您可以传递任何您想要的 keystore 和 trustore JVM 参数。对于 URL,您可以这样构造它:

    -Ddb_jdbc_url=jdbc:mysql://<host>:<port>/<db_name>?
useLegacyDatetimeCode=false&verifyServerCertificate=true&useSSL=true&requireSSL=true
&clientCertificateKeyStoreUrl=file:/user/documents/projects/trust-store-rds.jks
&clientCertificateKeyStorePassword=<password>
&clientCertificateKeyStoreType=JKS
&trustCertificateKeyStoreUrl=file:/user/documents/projects/trust-store-rds.jks
&trustCertificateKeyStorePassword=<password>
&trustCertificateKeyStoreType=JKS

请注意,对于 trustCertificateKeyStoreUrlclientCertificateKeyStoreUrl我正在传递相同的文件。

请注意,您还需要配置之前的所有步骤:

  1. 为数据库上的用户启用 SSL。
CREATE USER 'my_user'@'%' IDENTIFIED BY 'my_password';
ALTER USER 'my_user'@'%' REQUIRE SSL;
GRANT USAGE ON *.* TO 'my_user'@'%' REQUIRE SSL ;

  1. 您需要将 AWS 根证书和区域证书导入您的信任库;像这样:
     keytool -import -keystore trust-store-rds.jks -storepass changeit -noprompt alias "aws-rds-root" -file rds-ca-2015-root.pem

keytool -import -keystore trust-store-rds.jks -storepass changeit -noprompt -alias "aws-rds-us-east-1" -file rds-ca-2015-us-east-1.pem
  1. 如上所述构建 URL。

关于java - Spring Boot 连接到 AWS RDS MySQL - SSLHandshakeException : Received fatal alert: unknown_ca,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54662847/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com