MySQL配置SSL访问-WEB配置JDBC支持SSL

WEB配置JDBC支持SSL

Connector/J 可以使用 SSL 加密 JDBC 驱动程序和服务器之间通信的所有数据(初始握手除外)。启用连接加密会带来性能损失,其严重程度取决于多种因素,包括(但不限于)查询的大小、返回的数据量、服务器硬件、使用的 SSL 库、网络带宽、等等。

系统通过两个 Java 密钥库文件工作:一个文件包含服务器的证书信息(truststore在下面的示例中),另一个包含客户端的密钥和证书(keystore在下面的示例中)。所有 Java 密钥库文件都受到创建文件时提供给keytool的密码的保护 。您需要文件名和关联的密码才能创建 SSL 连接。

要使 SSL 支持起作用,您必须具备以下条件:

  • 一个支持 SSL 的 MySQL 服务器,并被编译和配置为这样做。

  • 签名的客户端证书,如果使用 双向(双向)身份验证。

默认情况下,Connector/J 与 MySQL 服务器建立安全连接。请注意,MySQL 服务器 5.7 和 8.0 在使用 OpenSSL 编译时,可以在启动时自动生成丢失的 SSL 文件并相应地配置 SSL 连接。

只要服务器正确配置为使用 SSL,就无需在 Connector/J 客户端上配置任何内容以使用加密连接(例外情况是 Connector/J 连接到非常旧的服务器版本,如 5.6.25 及更早版本)或 5.7.5 及更早版本,在这种情况下,客户端必须设置连接属性useSSL=true才能使用加密连接)。客户端可以通过设置连接属性来要求使用 SSL requireSSL=true;如果服务器未配置为使用 SSL,则连接将失败。如果没有 requireSSL=true,如果服务器未配置为使用 SSL,则连接只会回退到非加密模式。

为了提高安全性,您可以将客户端设置为单向(服务器或客户端)或双向(服务器和客户端)SSL 身份验证,允许客户端或服务器验证彼此的身份。

设置服务器身份验证

当连接器/J 连接属性verifyServerCertificate为 true(这是 时的默认设置 useSSL=true)时,通过服务器证书验证启用服务器身份验证 。

要验证服务器证书,Connector/J 需要能够读取为其签名的证书,即自己签名的服务器证书或自签名 CA 证书。这可以通过将证书(ca.pem或任何其他证书)导入 Java 默认信任库(尽管不建议篡改默认信任库)或通过将其导入自定义 Java 信任库文件并相应地配置连接器/J 驱动程序来实现。使用 Java 的 keytool(通常位于binJDK 或 JRE 安装的子目录中)导入服务器证书:

$> keytool -importcert -alias MySQLCACert -file ca.pem \
    -keystore truststore.jks -storepass mypassword

设置java数据库连接字符串

// mysql 5
Class.forName("com.mysql.jdbc.Driver").newInstance();
// mysql 8
//	Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
String url = "jdbc:mysql://192.168.5.132:3306/test?"
	+ "useSSL=true"
	+ "&verifyServerCertificate=true"
	+ "&requireSSL=true"
	+ "&trustCertificateKeyStoreUrl=file:D:/ssl.132/truststore.jks"
	+ "&trustCertificateKeyStorePassword=mypassword";

设置客户端身份验证

将客户端密钥和证书文件转换为 PKCS #12 存档:

$> openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \
  -name "mysqlclient" -passout pass:mypassword -out client-keystore.p12

将客户端密钥和证书导入 Java 密钥库:

$> keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 \
 -srcstorepass mypassword -destkeystore keystore.jks -deststoretype JKS -deststorepass mypassword

设置java数据库连接字符串

String url = "jdbc:mysql://192.168.5.132:3306/test?"
	+ "useSSL=true"
	+ "&verifyServerCertificate=true"
	+ "&requireSSL=true"
	+ "&trustCertificateKeyStoreUrl=file:D:/ssl.132/truststore.jks"
	+ "&trustCertificateKeyStorePassword=mypassword"
	+ "&clientCertificateKeyStoreUrl=file:D:/ssl.132/keystore.jks"
	+ "&clientCertificateKeyStorePassword=mypassword";

调试 SSL 连接

JSSE 会stdout 在您设置系统属性时 提供调试信息

-Djavax.net.debug=all

然后 Java 会告诉您正在使用哪些密钥库和信任库,以及在 SSL 握手和证书交换期间发生了什么。当您尝试调试失败的 SSL 连接时,这会很有帮助。

完整java示例

import java.sql.*;

public class TestMysqlSSL {
     
	/**
	 * ssl调试参数:-Djavax.net.debug=all
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
     
		testSSL();
	}

	/**
	 */
	private static void testSSL() {
     
		try {
     
			// mysql 5
			Class.forName("com.mysql.jdbc.Driver").newInstance();

			// mysql 8
//			Class.forName("com.mysql.cj.jdbc.Driver").newInstance();

			// 1.服务端开启SSL,客户端强制SSL连接
			// ALTER USER 'u1'@'192.168.5.1' REQUIRE SSL;
//			String url = "jdbc:mysql://192.168.5.132:3306/test?"
//					+ "useSSL=true"
//					+ "&verifyServerCertificate=false"
//					+ "&requireSSL=true";

			// 2. 服务端开启SSL,验证服务端证书
			// ALTER USER 'u1'@'192.168.5.1' REQUIRE SSL;
//			String url = "jdbc:mysql://192.168.5.132:3306/test?"
//					+ "allowMultiQueries=true&useUnicode&characterEncoding=UTF-8&autoReconnect=true"
//					+ "&useSSL=true"
//					+ "&verifyServerCertificate=true"
//					+ "&requireSSL=true"
//					+ "&trustCertificateKeyStoreUrl=file:D:/dev/mysql/ssl.132/truststore.jks"
//					+ "&trustCertificateKeyStorePassword=mypassword";

			// 3. 服务端开启SSL,配置证书,客户端连服务端,配置双向验证服务端证书和客户端证书
			// ALTER USER 'u1'@'192.168.5.1' REQUIRE X509; // 如果配置为X509,必须使用以下方式连接mysql
			String url = "jdbc:mysql://192.168.5.132:3306/test?" 
					+ "useSSL=true" 
					+ "&verifyServerCertificate=true"
					+ "&requireSSL=true" 
					+ "&trustCertificateKeyStoreUrl=file:D:/dev/mysql/ssl.132/truststore.jks"
					+ "&trustCertificateKeyStorePassword=mypassword"
					+ "&clientCertificateKeyStoreUrl=file:D:/dev/mysql/ssl.132/keystore.jks"
					+ "&clientCertificateKeyStorePassword=mypassword";

			String user = "u1";
			String password = "abcd@123";
			System.out.println("连接数据库");
			Connection conn = DriverManager.getConnection(url, user, password);
			System.out.println("连接正常!");

			PreparedStatement ps = conn.prepareStatement("SELECT sysdate() as t ");
			ResultSet rs = ps.executeQuery();
			rs.next();
			System.out.println("T=" + rs.getObject(1));
			conn.close();
		} catch (Exception sqle) {
     
			System.out.print(sqle);

		}
	}
}

参考

https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-using-ssl.html

你可能感兴趣的:(mysql,java,ssl,mysql)