【问题标题】:Failing to establish an Java SSLSocket connection to a secure mysql open socket无法建立与安全 mysql 开放套接字的 Java SSLSocket 连接
【发布时间】:2016-02-24 20:23:30
【问题描述】:

注意:我是 SSLSocket 新手...

我在 mysql 数据库(版本 5.7.9)和 java 应用程序(Java 1.8.0_U73)之间建立了安全连接,两者都在 localhost 上运行。数据库连接是使用 SpringFramework 4.2.4 API 创建的。我试图在数据库和 Java 应用程序通过 SpringFramework API 进行通信的同一个套接字上打开一个 Java SSLSocket,但没有成功。启动 ssl 套接字 startHandshake() 方法时出现的 printstack 错误是(注意 path to 替换了我正在运行的实际安装文件夹):

[*path to*\db\mysql\bin\mysqld, "--basedir=*path to*\db\mysql", "--datadir=*path to*\db\mysql\data", "--secure-file-priv=*path to*\db\mysql\data", --port=3355, "--ssl-ca=*path to*\db\mysql\data\cacert.pem", "--ssl-cert=*path to*\db\mysql\data\server-cert.pem", "--ssl-key=*path to*\db\mysql\data\server-key.pem"]
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    at sun.security.ssl.InputRecord.handleUnknownRecord(Unknown Source)
    at sun.security.ssl.InputRecord.read(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 TestSSL.testSocket(TestSSL.java:209)
    at TestSSL.main(TestSSL.java:253)

mysql 数据库从我下载的 mysql-5.7.11-winx64-debug-test.zip 中的示例 cacert.pem、server-cert.pem 和 server-key.pem 文件启动使用 --ssl-ca、--ssl-cert 和 --ssl-key 启动选项的 mysql 网站。

Mysql 日志文件显示 mysqld 启动的以下内容:

2016-02-24T19:37:06.710628Z 0 [注意] InnoDB:从 path to\db\mysql\data\ib_buffer_pool
加载缓冲池 2016-02-24T19:37:06.808638Z 0 [警告] CA 证书 路径\db\mysql\data\cacert.pem 是自签名的。
2016-02-24T19:37:06.819639Z 0 [注意] 服务器主机名(绑定地址):'*';端口:3355
2016-02-24T19:37:06.821639Z 0 [注意] IPv6 可用。
2016-02-24T19:37:06.822639Z 0 [注意] - '::' 解析为 '::';
2016-02-24T19:37:06.823639Z 0 [注意] 在 IP: '::' 上创建的服务器套接字。
2016-02-24T19:37:06.977655Z 0 [注意] InnoDB:缓冲池加载完成于 160224 12:37:06
2016-02-24T19:37:07.107668Z 0 [注意] 事件调度程序:已加载 0 个事件
2016-02-24T19:37:07.108668Z 0 [注意] 路径\db\mysql\bin\mysqld:准备连接。
版本:“5.7.9”套接字:“”端口:3355 MySQL 社区服务器 (GPL)

另外,使用 MySQL Workbench 快速连接到 mysql 数据库显示:

连接:
名称:MyConnection64
主机:本地主机
端口:3355
服务器:MySQL 社区服务器 (GPL)
版本:5.7.9
登录用户:root
当前用户:root@localhost
SSL:使用 DHE-RSA-AES256-SHA

用于创建 Java SpringFramework 数据库连接的 URL 是(来自我的 SpringFramework dbaccess.xml 文件):

入口键="db.jdbcurl" value="jdbc:mysql://localhost:3355/imom?useServerPrepStmts=false&rewriteBatchedStatements=true&server.basedir=路径\db\mysql&server.datadir=路径\db \mysql\data&createDatabaseIfNotExist=true&autoReconnect=true&useSSL=true"

我用来启动我的 java 应用程序的 VM 参数是:
-Djavax.net.ssl.keyStore="path to\db\mysql\data\keystore" -Djavax. net.ssl.keyStorePassword="changeme" -Djavax.net.ssl.trustStore="路径\db\mysql\data\truststore" -Djavax.net.ssl.trustStorePassword="changeme"

我正在使用(成功)创建 SpringFramework 连接的代码是:

private static void testSpring() {

    try {
        Connection conn = DataSourceUtils.getConnection(m_dataSource);
        conn.close();
    } catch (Exception ex) {
        System.out.println(ex.getMessage());
        ex.printStackTrace();
    }
}

我用来创建 SSLSocket 的代码(不成功)是:

private static void testSocket() {
//      System.setProperty("jsse.enableSNIExtension", "false");
//      System.setProperty("jsse.enabledSSLCipherSuites", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA");

    try {
        Socket socket = new Socket(m_hostnameString, Integer.parseInt(m_portString));
        InputStream keyStoreResource = new FileInputStream(m_baseDir
                + File.separator + "data" + File.separator + "keystore");
        char[] keyStorePassphrase = "changeme".toCharArray();
        KeyStore ksKeys = KeyStore.getInstance("JKS");
        ksKeys.load(keyStoreResource, keyStorePassphrase);

        // KeyManager decides which key material to use.
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ksKeys, keyStorePassphrase);

        InputStream trustStoreIS = new FileInputStream(m_baseDir
                + File.separator + "data" + File.separator + "truststore");
        char[] trustStorePassphrase = "changeme".toCharArray();
        KeyStore ksTrust = KeyStore.getInstance("JKS");
        ksTrust.load(trustStoreIS, trustStorePassphrase);

        // TrustManager decides which certificate authorities to use.
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance("SunX509");
        tmf.init(ksTrust);

//          SSLSocketFactoryEx factory = new SSLSocketFactoryEx(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, m_hostnameString, Integer.parseInt(m_portString),true);

        // and go!
        sslSocket.startHandshake();
    }
    catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (CertificateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

【问题讨论】:

    标签: java mysql spring ssl


    【解决方案1】:

    我有点困惑,为什么您要使用自己的 SSL 套接字直接连接到 MySQL 实例。通常,您仍然希望通过任何机制(Spring、JPA 等)使用 JDBC 库并告诉 it 使用 SSL。正如您不想使用“普通”套接字直接连接到 MySQL 服务器一样,您也不想使用 SSL。请参阅this page 了解更多信息。

    【讨论】:

    • @JanetM 但无论如何他都做不到。他将获得一个BindException 创建第二个监听套接字。
    • @JanetM 无论如何,如果它只是一个存在检查,你不需要握手甚至 SSL。
    • 谢谢。那也行。我使用这个练习来增加我对 SSLSockets 的总体理解,因为我还有其他应用程序打开的套接字也需要被 SSL 锁定。
    • 我对 SSL 握手失败的原因更感兴趣。我正在使用这个练习来增加我对 SSLSockets 的总体理解,因为我还有其他应用程序打开的套接字也需要使用 SSL 锁定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多