TLCP 传输加密
简介
TLCP (Transport layer cryptography protocol) 是基于当前通用的 TLS/SSL,构建的基于国密算法 SM2 证书的国密算法套 (SM4-SM3) 的安全传输协议,可以称为国密版本SSL。在平凯数据库中要启用 TLCP,需要 TiDB server 端和所用的 client 端同时修改有关配置,否则无法启用 TLCP 传输加密。
TiDB server 配置
修改 config 文件,添加证书及密钥路径
TLCP 加密和签名使用两套秘钥,需要在 config 文件中配置对应的绝对路径,之后按正常流程启动即可。测试证书、秘钥见下一节。
# Path of file that contains trusted TLCP CA for connection with mysql client.
tlcp-ca = ""
# Path of file that contains X509 TLCP signature certificate for connection with mysql client.
tlcp-sig-cert = ""
# Path of file that contains X509 TLCP signature key for connection with mysql client.
tlcp-sig-key = ""
# Path of file that contains X509 TLCP encryption certificate for connection with mysql client.
tlcp-enc-cert = ""
# Path of file that contains X509 TLCP encryption key for connection with mysql client.
tlcp-enc-key = ""
生成证书、秘钥【仅测试用】
TLCP 所用的证书秘钥与 TLS 不同。这里选择使用铜锁密码库生成测试用的密钥、证书,有两种方法可选。
方法 1. 安装铜锁密码库
方法 2. 使用已配置好的 Docker
启动 Docker。
执行
/root/gen_sm2_certs/cert.sh脚本即可生成测试用全套证书秘钥。测试用得到的证书共有如图的 5 个。TiDB server 使用的证书和秘钥对应关系为:
tlcp-ca = "/path/to/subca.crt" tlcp-sig-cert = "/path/to/server_sign.crt" tlcp-sig-key = "/path/to/server_sign.key" tlcp-enc-cert = "/path/to/server_enc.crt" tlcp-enc-key = "/path/to/server_enc.key"
Client 配置
目前与 TiDB server 配套的可以使用 TLCP 传输加密的客户端有两个,JDBC 和 go-driver
go sql driver 配置
安装此 repo 中的 go sql driver。
go get -u github.com/fzzf678/mysql_tlcp@v0.0.16将 CA 证书存放在系统的
/tmp路径下。配置 dsn 参数。除原有配置外,在 dataSourceName 中需要指定 tlcp 开关以及 CA 证书名。
tlcp=true tlcpCaPath=证书名建立连接。例如:
package main import ( "database/sql" "fmt" _ "github.com/fzzf678/mysql_tlcp" ) var ( dsn = "root:@tcp(127.0.0.1:4000)/mysql?tlcp=true&tlcpCaPath=subca.crt" ) func main() { db, err := sql.Open("mysql", dsn) dealErr(err) defer db.Close() //... } func dealErr(err error) { if err != nil { panic(err) } }
mysql-connector-j 配置
下载 release/8.0-tlcp 分支中的
mysql-connector-java-8.0.29-SNAPSHOT.jar到本地。修改 Maven 项目的
pom.xml,添加腾讯 kona 库的 dependencies,并将 mysql-connector-java 依赖设置为上一步本地的 jar 包(假设存放在项目路径的 lib 目录中):<dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> <scope>system</scope> <systemPath> ${project.basedir}/lib/mysql-connector-java-8.0.29-SNAPSHOT.jar </systemPath> </dependency> <!-- https://mvnrepository.com/artifact/com.tencent.kona/kona-ssl --> <dependency> <groupId>com.tencent.kona</groupId> <artifactId>kona-ssl</artifactId> <version>1.0.9</version> </dependency> <!-- https://mvnrepository.com/artifact/com.tencent.kona/kona-crypto --> <dependency> <groupId>com.tencent.kona</groupId> <artifactId>kona-crypto</artifactId> <version>1.0.9</version> <!-- <scope>runtime</scope>--> </dependency> <!-- https://mvnrepository.com/artifact/com.tencent.kona/kona-pkix --> <dependency> <groupId>com.tencent.kona</groupId> <artifactId>kona-pkix</artifactId> <version>1.0.9</version> <!-- <scope>runtime</scope>--> </dependency> <!-- https://mvnrepository.com/artifact/com.tencent.kona/kona-provider --> <dependency> <groupId>com.tencent.kona</groupId> <artifactId>kona-provider</artifactId> <version>1.0.9</version> </dependency> </dependencies>使用 kona 库提供的 jar 包将 TongSuo 库自带的
chain-ca.crt转换成 keystore:java -cp kona-crypto-1.0.9.jar:kona-pkix-1.0.9.jar:kona-ssl-1.0.9.jar com.tencent.kona.pkix.tool.KeyStoreTool \ -type JKS \ -alias trust1,trust2 \ -certs chain-ca.crt \ -store store.p12 \ -storePasswd ''编写测试类 TestTLCP:
package org.example; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.util.Properties; public class TestTLCP { private static final String TLCP_MODE = "REQUIRED"; private static final String trustTlcpCertificateKeyStoreUrl = "file:store.p12"; // 设置为上一步得到的 store.p12 路径 public static void main(String[] args) { String rawURL = "jdbc:mysql://localhost:4000/test?"; Properties properties = getProperties(); String[] queries = { "SHOW STATUS LIKE \"%tlcp%\"" }; try { // 注册 JDBC 驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 打开连接 Connection conn = DriverManager.getConnection( rawURL, properties ); // 创建用于执行SQL语句的Statement对象 Statement stmt = conn.createStatement(); for (String query : queries) { TestSSL.query(stmt, query); } // 关闭资源 stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } private static Properties getProperties() { Properties properties = new Properties(); properties.setProperty("user", "root"); properties.setProperty("password", ""); properties.setProperty("sslMode", "DISABLED"); properties.setProperty("tlcpMode", TLCP_MODE); properties.setProperty("trustTlcpCertificateKeyStoreUrl", trustTlcpCertificateKeyStoreUrl); return properties; } }
检查当前连接是否是加密连接
可以通过 SHOW STATUS LIKE "%tlcp%"; 了解当前连接的详细情况,包括是否使用了安全连接、安全连接采用的加密协议、TLS 版本号等。以下是一个 TLCP 连接中执行该语句的结果。由于客户端支持的加密协议会有所不同,执行结果相应地也会有所变化。
tlcp_cipher ECC_SM4_GCM_SM3
tlcp_cipher_list ECC_SM4_GCM_SM3:ECC_SM4_CBC_SM3:ECDHE_SM4_GCM_SM3:ECDHE_SM4_CBC_SM3:
tlcp_server_enc_not_after Jan 29 02:30:14 2123 UTC
tlcp_server_enc_not_before Feb 22 02:30:14 2023 UTC
tlcp_server_sign_not_after Jan 29 02:30:14 2123 UTC
tlcp_server_sign_not_before Feb 22 02:30:14 2023 UTC
tlcp_version TLCPv1.1