【问题标题】:MySQL JDBC encryption using SSL使用 SSL 的 MySQL JDBC 加密
【发布时间】:2018-07-19 04:18:42
【问题描述】:

MySQL 服务器(在 Red Hat 7 操作系统上运行的远程机器,MySQL 版本为 5.7.11)启用了 SSL,如下所示:

+---------------+--------------------------------+
| Variable_name | Value                          |
+---------------+--------------------------------+
| have_openssl  | YES                            |
| have_ssl      | YES                            |
| ssl_ca        | /var/lib/mysql/ca.pem          |
| ssl_capath    |                                |
| ssl_cert      | /var/lib/mysql/server-cert.pem |
| ssl_cipher    |                                |
| ssl_crl       |                                |
| ssl_crlpath   |                                |
| ssl_key       | /var/lib/mysql/server-key.pem  |

我正在尝试从我的本地机器(Windows)使用 SSL(不是身份验证)建立 JDBC 加密。下面是执行此操作的 JDBC 代码:

import java.sql.*;

public class MysqlConnect
{
    public static void main (String[] args)
    {
        try
        {
            //System.setProperty("javax.net.ssl.trustStore", "cacerts");
            //System.setProperty("javax.net.ssl.trustStorePassword", "changeit");    ( Works with truststore values , but gives the error below without it)
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            String url = "jdbc:mysql://IPAddress:3306/DBName?
            verifyServerCertificate=false&useSSL=true&requireSSL=true";
            String user = "root";
            String password = "password";
            Connection con = DriverManager.getConnection(url,user,password);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

我已按照此链接创建证书:https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html .现在,如果我将服务器证书添加到 C:\Program Files\Java\jdk1.8\jre\lib\security\cacerts 并使用此信任库,我确实会在 wireshark 中看到加密连接,但是如果我不提供信任库名称和密码我收到以下错误(我这样做的原因是因为根据我的理解与 ssl 身份验证不同,使用 ssl 的 jdbc 加密不应该需要客户端信任库参数):

javax.net.ssl.SSLHandshakeException
MESSAGE: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

STACKTRACE:

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) .

我的问题是,即使尝试仅使用 ssl(不是 SSL 身份验证)进行 jdbc 加密,是否也需要将服务器证书添加到客户端信任库(并提供信任库详细信息)?。

我已经看过这个相关链接:

JDBC parameter verifyServerCertificate=false connects without the need for a clientkeystore and truststore

但我仍然收到 verifyServerCertificate=false 的错误(它取决于 MySQL 版本还是使用自签名证书)?

【问题讨论】:

  • 当服务器证书未由有效的 CA 签名时,通常需要在 java 中将服务器证书添加到客户端信任库。您能否提供有关服务器证书的更多详细信息?您使用的是 JRE 信任库还是外部信任库?
  • @yopablo ,我正在做 ssl 加密而不是 ssl 身份验证,这需要将服务器证书添加到客户端信任库。我认为阅读 2 路 SSL 身份验证、1 路 SSL 身份验证和 ssl 加密将帮助您清除这个点。
  • 如果您阅读文档(dev.mysql.com/doc/connector-j/5.1/en/…,“verifyServerCertificate”部分),它说您也需要使用“clientCertificateKeyStore”参数

标签: java mysql ssl encryption jdbc


【解决方案1】:

代码在不同的系统上运行良好,我可以建立安全连接,它失败的确切原因仍然未知,但这是我的假设 -> 即使我没有在我的 jdbc 代码中使用 cacerts(truststore)似乎远程服务器已在某处保存了客户端身份,并且仍在引用该身份。

如果有人遇到类似问题,您可以尝试重新创建服务器证书并重新启动您的数据库服务器,并出于理智目的从信任库中删除相应的证书或创建并使用新的信任库。

在wireshark中你应该看到这样的东西:

1   source IP   Dest IP TLSv1.2 220 Client Hello
2   Dest IP     source IP TLSv1.2   1140    Server Hello, Certificate, Server Key Exchange, Server Hello Done
3   source IP   Dest IP TLSv1.2 129 Client Key Exchange
4   source IP   Dest IP TLSv1.2 60  Change Cipher Spec
5   source IP   Dest IP TLSv1.2 99  Encrypted Handshake Message

如果您在 Wireshark 中看到此内容,则表示您现在已通过 ssl 加密链接连接(显然这只是一种解决方法,因为此行为的根本原因仍然未知)。

【讨论】:

    【解决方案2】:

    使用 SSL 的 JDBC 加密不需要客户端信任库参数

    是什么让你这么想?你误会了。如果您使用的是自签名证书,则可以。

    【讨论】:

    • 对不起,我想我以前听不懂您的评论,所以您是说使用自签名证书时使用 SSL 的 JDBC 加密总是需要客户端信任库参数? .您能否在提到它的地方提及文档或链接,这将非常有帮助。但这很奇怪,因为我可以建立到远程 MySQL 和 PostgreSQL 服务器的 ssl ecnrypted 链接,并且我可以看到wireshark 前面评论中提到的数据,它清楚地显示了 TLSv1.2 和使用服务器证书和密钥交换的加密握手。
    猜你喜欢
    • 2018-07-31
    • 1970-01-01
    • 2017-04-07
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多