通過JDBC連接實例的方式有無需下載SSL證書連接和用戶下載SSL證書連接兩種,其中使用SSL證書連接通過了加密功能,具有更高的安全性。RDS for MySQL新實例默認關閉SSL數據加密,開啟SSL請參考設置SSL數據加密。SSL連接實現了數據加密功能,但同時也會增加網絡連接響應時間和CPU消耗,不建議開啟SSL數據加密。
前提條件
用戶需要具備以下技能:
- 熟悉計算機基礎知識。 
- 了解java編程語言。 
- 了解JDBC基礎知識。 
使用SSL證書連接
說明
使用SSL證書連接實例,即通過證書校驗并連接數據庫。RDS for MySQL實例不支持X509認證方式。
步驟 1 下載CA證書或捆綁包。
1. 在“實例管理”頁面,單擊實例名稱進入“基本信息”頁面。
2. 單擊“SSL”處的“下載”。
步驟 2 使用keytool工具通過CA證書生成truststore文件。
<keytool工具的安裝路徑> ./keytool.exe -importcert -alias <MySQLCACert> --file <ca.pem> -keystore <truststore_file> -storepass <password>表 變量說明
| 變量 | 說明 | 
|---|---|
| <keytool工具的安裝路徑> | 請替換為JDK或JRE安裝路徑的bin目錄,例如C:\Program Files (x86)\Java\jdk-11.0.7\bin。 | 
| <MySQLCACert> | 請設置truststore文件的名稱。建議設置為具有業務意義的名稱,便于后續識別。 | 
| <ca.pem> | 請替換為步驟1中下載解壓后CA證書的名稱,例如ca.pem。 | 
| <truststore_file> | 請設置truststore文件的存放路徑。 | 
| <password> | 請設置truststore文件的密碼。 | 
代碼示例(使用JDK安裝路徑下的keytool工具生成truststore文件):
Owner:  CN=MySQL_Server_5.7.17_Auto_Generated_CA_Certificate 
Issuer: CN=MySQL_Server_5.7.17_Auto_Generated_CA_Certificate  
Serial number: 1 
Valid from: Thu Feb 16 11:42:43 EST 2017 until: Sun Feb 14 11:42:43 EST 2027  
Certificate fingerprints: 
     MD5: 18:87:97:37:EA:CB:0B:5A:24:AB:27:76:45:A4:78:C1 
     SHA1: 2B:0D:D9:69:2C:99:BF:1E:2A:25:4E:8D:2D:38:B8:70:66:47:FA:ED  
     SHA256:C3:29:67:1B:E5:37:06:F7:A9:93:DF:C7:B3:27:5E:09:C7:FD:EE:2D:18:86:F4:9C:40:D8:26:CB:DA:95: A0:24 
     Signature algorithm name: SHA256withRSA Subject Public Key Algorithm: 2048-bit RSA key  
     Version: 1 
     Trust this certificate? [no]: y 
     Certificate was added to keystore步驟 3 通過JDBC連接MySQL數據庫,代碼中的JDBC連接格式如下:
jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?param1=value1¶m2=value2表 參數說明
| 參數 | 說明 | 
|---|---|
| <instance_ip> | 請替換為實例的IP地址。 說明 
 | 
| <instance_port> | 請替換為實例的數據庫端口,默認為3306。 說明 您可以在該實例的“連接管理”頁面查看。 | 
| <database_name> | 請替換為連接實例使用的數據庫名,默認為mysql。 | 
| <param1> | requireSSL,用于設置服務端是否支持SSL連接。取值如下: 
 說明 requireSSL與其他連接參數、sslMode之間的關系請參考表 連接參數與SSLMode的關系說明。 | 
| <param2> | useSSL,用于設置客戶端是否使用SSL連接服務端。取值如下: 
 說明 useSSL與其他連接參數、sslMode之間的關系請參考表 連接參數與SSLMode的關系說明。 | 
| <param3> | verifyServerCertificate,客戶端是否校驗服務端的證書。取值如下: 
 說明 verifyServerCertificate與其他連接參數、sslMode之間的關系請參考表 連接參數與SSLMode的關系說明。 | 
| <param4> | trustCertificateKeyStoreUrl,取值為file:<truststore_file>。 <truststore_file>請替換為步驟2中truststore文件設置的存儲路徑。 | 
| <param5> | trustCertificateKeyStorePassword,取值為步驟2中truststore文件設置的密碼。 | 
表 連接參數與SSLMode的關系說明
| useSSL | requireSSL | verifyServerCertificate | sslMode | 
|---|---|---|---|
| false | 不涉及 | 不涉及 | DISABLED | 
| true | false | false | PREFERRED | 
| true | true | false | REQUIRED | 
| true | 不涉及 | true | VERIFY_CA | 
代碼示例(連接MySQL數據庫的java代碼):
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.ResultSet;  
import java.sql.Statement; 
import java.sql.SQLException;  
 
// 認證用的用戶名和密碼直接寫到代碼中有很大的安全風險,建議在配置文件或者環境變量中存放(密碼應密文存放,使用時解密),確保安全。 
// 本示例以用戶名和密碼保存在環境變量中為例,運行本示例前請先在本地環境中設置環境變量(環境變量名稱請根據自身情況進行設置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 
public class JDBCTest {  
    
 
    String USER = System.getenv("EXAMPLE_USERNAME_ENV");          
    String PASS = System.getenv("EXAMPLE_PASSWORD_ENV"); 
 
    public static void main(String[] args) { 
        Connection conn = null;  
        Statement stmt = null; 
 
       // url中所需的連接參數根據實際情況配置 
       String url = "jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?param1=value1¶m2=value2"; 
  
        try {  
            Class.forName("com.mysql.cj.jdbc.Driver")? 
            conn = DriverManager.getConnection(url, USER, PASS)? 
  
            stmt = conn.createStatement();  
            String sql = "show status like 'ssl%'"? 
            ResultSet rs = stmt.executeQuery(sql);  
 
            int columns = rs.getMetaData().getColumnCount()? 
            for (int i = 1? i <= columns? i++) { 
                System.out.print(rs.getMetaData().getColumnName(i))? 
                System.out.print("\t")? 
            } 
 
            while (rs.next()) {  
                System.out.println();  
                for (int i = 1? i <= columns? i++) { 
                    System.out.print(rs.getObject(i))? 
                    System.out.print("\t")? 
                }  
            } 
            rs.close();  
            stmt.close();  
            conn.close();  
        } catch (SQLException se) {  
            se.printStackTrace();  
        } catch (Exception e) {  
            e.printStackTrace()?  
        } finally {  
            // release resource ....  
        }  
    }  
}----結束
無證書連接
說明
該方式不對服務端進行證書校驗,用戶無需下載SSL證書。
步驟 1 通過JDBC連接RDS for MySQL數據庫實例,代碼中的JDBC連接格式如下:
jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?useSSL=false表 變量說明
| 變量 | 說明 | 
|---|---|
| <instance_ip> | 請替換為實例的IP地址。 說明 
 | 
| <instance_port> | 請替換為實例的數據庫端口,默認為3306。 說明 您可以在該實例的“連接管理”頁面查看。 | 
| <database_name> | 請替換為連接實例使用的數據庫名,默認為mysql。 | 
代碼示例(連接MySQL數據庫的java代碼):
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 
// 認證用的用戶名和密碼直接寫到代碼中有很大的安全風險,建議在配置文件或者環境變量中存放(密碼應密文存放,使用時解密),確保安全。 
// 本示例以用戶名和密碼保存在環境變量中為例,運行本示例前請先在本地環境中設置環境變量(環境變量名稱請根據自身情況進行設置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 
 
public class MyConnTest { 
	final public static void main(String[] args) { 
		Connection conn = null; 
 
                // url中所需的連接參數根據實際情況配置 
                String url = "jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?param1=value1¶m2=value2"; 
                String USER = System.getenv("EXAMPLE_USERNAME_ENV");          
                String PASS = System.getenv("EXAMPLE_PASSWORD_ENV"); 
		try { 
			Class.forName("com.mysql.jdbc.Driver"); 
			 
                        conn = DriverManager.getConnection(url,USER,PASS); 
			System.out.println("Database connected"); 
 
			Statement stmt = conn.createStatement(); 
			ResultSet rs = stmt.executeQuery("SELECT * FROM mytable WHERE columnfoo = 500"); 
			while (rs.next()) { 
				System.out.println(rs.getString(1)); 
			} 
			rs.close(); 
			stmt.close(); 
			conn.close(); 
		} catch (Exception e) { 
			e.printStackTrace(); 
			System.out.println("Test failed"); 
		} finally { 
			// release resource .... 
		} 
	} 
}----結束
相關問題
- 問題描述 
當您使用8.0及以上版本的JDK通過SSL證書模式連接MySQL時,報如下類似錯誤:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or 
cipher suites are inappropriate) 
    at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171) ~[na:1.8.0_292] 
    at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98) ~ 
[na:1.8.0_292] 
    at sun.security.ssl.TransportContext.kickstart(TransportContext.java:220) ~ 
[na:1.8.0_292] 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:428) ~ 
[na:1.8.0_292] 
    at 
com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:316) ~ 
[mysql-connector-java-8.0.17.jar:8.0.17] 
    at 
com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java 
:188) ~[mysql-connector-java8.0.17.jar:8.0.17] 
    at 
com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection. 
java:99) ~[mysql-connector-java8.0.17.jar:8.0.17] 
    at 
com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:331) ~ 
[mysql-connector-java8.0.17.jar:8.0.17] 
... 68 common frames omitted- 解決方法 
您可以在步驟3中的代碼鏈路中,根據客戶端使用的Jar包指定對應參數值進行連接。示例如下:
? mysql-connector-java-5.1.xx.jar(對于8.0.18及以前版本的連接驅動,使用enabledTLSProtocols參數,詳見)
在數據庫連接url:jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?param1=value1¶m2=value2 的末尾以param1=value1的形式增加enabledTLSProtocols=TLSv1.2? mysql-connector-java-8.0.xx.jar(對于8.0.18以后版本的連接驅動,使用tlsVersions參數)
在數據庫連接url:jdbc:mysql://<instance_ip>:<instance_port>/<database_name>?param1=value1¶m2=value2 的末尾以param1=value1的形式增加tlsVersions=TLSv1.2
