Java 使用SSL的MySQL JDBC加密
MySQL服务器(运行在Red Hat 7操作系统上的远程计算机,MySQL版本为5.7.11)已启用SSL,如下所示:Java 使用SSL的MySQL JDBC加密,java,mysql,ssl,encryption,jdbc,Java,Mysql,Ssl,Encryption,Jdbc,MySQL服务器(运行在Red Hat 7操作系统上的远程计算机,MySQL版本为5.7.11)已启用SSL,如下所示: +---------------+--------------------------------+ | Variable_name | Value | +---------------+--------------------------------+ | have_openssl | YES
+---------------+--------------------------------+
| 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();
}
}
}
我已按照此链接创建证书:
. 现在,如果我将服务器证书添加到C:\Program Files\Java\jdk1.8\jre\lib\security\cacerts并使用此信任库,我确实会在wireshark中看到一个加密连接,但是如果我不提供信任库名称和密码,我会得到以下错误(我这样做的原因是,根据我的理解,与ssl身份验证不同,使用ssl的jdbc加密不需要客户端信任库参数):
我的问题是,即使尝试仅使用ssl(而不是ssl身份验证)进行jdbc加密,是否也需要将服务器证书添加到客户端信任库(并提供信任库详细信息)
我已经看到了这个相关链接:
但是我仍然得到verifyServerCertificate=false的错误(这取决于MySQL版本还是使用自签名证书)?代码在不同的系统中运行良好,我可以建立安全连接,失败的确切原因仍然未知,但这是我的假设->即使我没有使用cacerts(truststore)在我的jdbc代码中,远程服务器似乎已将客户机标识保存在某个地方,并且仍在引用该标识 如果有人面临类似的问题,您可以尝试重新创建服务器证书并重新启动db服务器,仅出于正常目的,从信任库中删除相应的证书或创建并使用新的信任库 在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 enycrypted链接进行连接(显然这只是一种解决方法,因为这种行为的根本原因尚不清楚)
使用SSL的JDBC加密不应要求客户端信任库参数
是什么让你这么想的?你错了。如果你使用的是自签名证书,就错了。很抱歉,我想我以前无法理解你的评论,所以你是说在使用自签名证书时使用SSL的JDBC加密将始终需要客户端信任库参数吗?你能提到我使用的文档或链接吗s这么说,这真的很有帮助。但奇怪的是,我可以建立到远程MySQL和PostgreSQL服务器的ssl加密链接,我可以看到wireshark在前面的评论中提到的数据,该评论清楚地显示了TLSv1.2和使用服务器证书和密钥交换的加密握手。向clie添加服务器证书在java中,当服务器证书未经有效CA签名时,通常需要nt trustore。您能提供有关服务器证书的更多详细信息吗?您使用的是JRE trustore还是外部证书?@yopablo,我正在进行ssl加密,而不是ssl身份验证,这需要将服务器证书添加到客户端信任库。我想阅读t双向SSL身份验证、单向SSL身份验证和SSL加密将帮助您明确这一点。如果您阅读文档(,部分“verifyServerCertificate”),它会说您也需要使用“clientCertificateKeyStore”参数
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