注意:我是SSLSocket新手......
我在一个运行在localhost上的mysql数据库(版本5.7.9)和一个java应用程序(Java 1.8.0_U73)之间建立了安全连接。使用SpringFramework 4.2.4 API创建数据库连接。我试图在数据库和java应用程序通过SpringFramework API进行通信的同一个套接字上打开一个Java SSLSocket但没有成功。我在启动ssl socket startHandshake()方法时遇到的printstack错误是(注意 的路径替换了我正在运行的实际安装文件夹):
[*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)
使用示例cacert.pem,server-cert.pem和server-key.pem文件启动mysql数据库,该文件可以在我从以下网址下载的mysql-5.7.11-winx64-debug-test.zip中找到mysql网站使用--ssl-ca, - ssl-cert和--ssl-key启动选项。
Mysql日志文件显示mysqld启动的以下内容:
2016-02-24T19:37:06.710628Z 0 [注意] InnoDB:从路径加载缓冲池到 \ 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 [注意]服务器主机名(绑定地址):' *&#39 ;;港口: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
主持人:localhost
港口:3355
服务器:MySQL社区服务器(GPL)
版本:5.7.9
登录用户:root
当前用户:root @ localhost
SSL:使用DHE-RSA-AES256-SHA
创建Java SpringFramework数据库连接的URL是(来自我的SpringFramework dbaccess.xml文件):
entry key =" 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 =" \ db \ mysql \ data \ keystore&的路径#34; -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();
}
}
答案 0 :(得分:1)
我对您为什么直接使用自己的SSL套接字连接MySQL实例感到有些困惑。通常,您仍然希望通过任何机制(Spring,JPA等)使用JDBC库,并告诉 it 使用SSL。正如您不希望使用" normal"直接连接到MySQL服务器一样。套接字,您也不想使用SSL。有关详细信息,请参阅this page。