繁体   English   中英

无法建立与安全mysql开放套接字的Java SSLSocket连接

[英]Failing to establish an Java SSLSocket connection to a secure mysql open socket

注意:我是SSLSocket的新手。

我在mysql数据库(版本5.7.9)和java应用程序(Java 1.8.0_U73)之间都具有安全连接,它们都在本地主机上运行。 数据库连接是使用SpringFramework 4.2.4 API创建的。 我试图在数据库和Java应用程序通过SpringFramework API进行通信的同一套接字上打开Java SSLSocket,但未成功。 启动ssl套接字startHandshake()方法时遇到的打印堆栈错误是(请注意替换从中运行的实际安装文件夹的路径 ):

[*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数据库以示例cacert.pem,server-cert.pem和server-key.pem文件启动,这些文件可以从我从mysql网站下载的mysql-5.7.11-winx64-debug-test.zip中找到。使用--ssl-ca,-ssl-cert和--ssl-key启动选项。

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

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

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

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

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

输入键= “db.jdbcurl”值=“的jdbc:mysql的://本地主机:3355 / imom useServerPrepStmts =假rewriteBatchedStatements =真server.basedir = 路径 \\ DB \\ mysql的&server.datadir = 路径 \\ DB \\ mysql的\\数据及createDatabaseIfNotExist =真autoReconnect的=真useSSL =真”

我用来启动Java应用程序的VM参数是:
-Djavax.net.ssl.keyStore =“ \\ 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();
    }

}

对于您为什么直接使用自己的SSL套接字直接连接到MySQL实例,我有些困惑。 通常,您仍然希望通过任何机制(Spring,JPA等)使用JDBC库,并告诉使用SSL。 正如您不想使用“普通”套接字直接连接到MySQL服务器一样,您也不想使用SSL。 请参阅此页面以获取更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM