在使用全密态MySQL时,目前只支持使用MySQL的Text Protocol。全密态MySQL在MySQL服务端返回的ResultSet上,对目标敏感数据进行加密。为了正确拿到密文,您必须首先对MySQL的Text Protocol进行正确解析。为了让客户端需要能够正确处理密文的ResultSet,阿里云推出了全密态客户端Java SDK模块(即EncDB SDK)。EncDB SDK提供了可信密钥管理、数据加解密、端到端安全通信功能。本文档介绍如何使用EncDB SDK访问数据库。
准备工作
获取加密数据库连接信息。您首先需要获取加密数据库的连接信息,如域名(host)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等。
配置加密规则。具体操作请参见新建加密规则。
配置Java SDK(EncDB SDK)
在您的Maven项目里添加依赖:
<dependencies>
...
<!-- 任意版本mysql conenctor都行 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>com.alibaba.encdb</groupId>
<artifactId>libencdb</artifactId>
<version>1.2.11-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.62</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.62</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.23</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.1.1-jre</version>
</dependency>
...
</dependencies>
配置示例
您可以使用任何形式的MySQL客户端(只要能正确解析MySQL Text Protocol),并在此基础上使用EncDB SDK对密文进行处理。以下示例是基于社区版MySQL JDBC和EncDB SDK构建的DEMO(需要在pom里额外引入MySQL JDBC),请用一个全密态PolarDB MySQL版的集群连接信息来完成下面的Demo,并且对enc_int
列配置加密规则。
// 请填入全密态PolarDB MySQL的集群连接信息(注意不要是主地址)
String hostname = "asodijasdoijaisd.rwlb.rds.aliyuncs.com";
String port = "3306";
String dbname = "test_db";
String username = "ruanbu";
String password = "123456Abc!";
Class.forName("com.mysql.cj.jdbc.Driver");
String dbUrl = String.format("jdbc:mysql://%s:%s/%s", hostname, port, dbname);
java.sql.Connection conn = java.sql.DriverManager.getConnection(dbUrl, username, password);
// 用户密钥,demo内手写一个32位的16进制串即可
String mek = "00112233445566778899aabbccddeeff";
com.alibaba.encdb.EncdbSDK sdk =
com.alibaba.encdb.crypto.EncdbSDKBuilder.newInstance()
.setKeyMgmtType(com.alibaba.encdb.common.Constants.KeyMgmtType.MYSQL_PROXY)
.setDbConnection(conn)
.setMek(mek)
.build();
com.alibaba.encdb.Cryptor cryptor = sdk.getCryptor();
// 建表测试
conn.createStatement().executeUpdate("drop table if exists test");
conn.createStatement().executeUpdate("create table test (enc_int int)");
conn.createStatement().executeUpdate("insert into test values (1)");
java.sql.ResultSet rs = conn.createStatement().executeQuery("select * from test");
rs.next();
// 获取密文字节流
byte[] cipher = rs.getBytes(1);
// 调用Cryptor.decrypt方法获取明文字节流
byte[] plaintext = cryptor.decrypt(cipher);
// 输出,对比明密文
System.out.println("明文:" + new String(plaintext) + " 密文:" + new String(cipher));
输出:
明文:1 密文:QmEA/4d0ROXfA3QeUZFiu7EdlvZy4Yaa+uDnyFHvFOnVK4dtgVIzjrYI54I=
Java SDK(EncDB SDK)API介绍
EncdbSDKBuilder
即com.alibaba.encdb.crypto.EncdbSDKBuilder
,它是一个EncdbSDK
类的构造类,使用中您需要以下API:// 获取一个新的EncdbSDKBuilder实例。您总是应该用这个方法来构造EncdbSDKBuilder。 EncdbSDKBuilder newInstance(); // (必选)设置一个数据库连接,用于EncDB SDK相关的密钥管理动作。这个数据库连接可以独立于业务中实际用到的数据库连接。 EncdbSDKBuilder setDbConnection(java.sql.Connection dbConnection); // (必选)设置EncDB SDK对接的客户端类型。对于全密态MySQL,您应该设置MYSQL_PROXY选项 EncdbSDKBuilder setKeyMgmtType(KeyMgmtType kmType); // (必选)设置用户主密钥。这里我们要求一个128位(即16字节)的byte[]对象 EncdbSDKBuilder setMek(byte[] mek); // (可选)设置加密算法。可选项有AES_128_GCM、AES_128_CTR、AES_128_CBC、AES_128_ECB、SM4_128_CBC、SM4_128_ECB、SM4_128_GCM、SM4_128_CTR。不设置的话默认为SM4_128_CBC。 EncdbSDKBuilder setEncAlgo(EncAlgo encAlgo); // 在完成上述设置之后,构造一个EncdbSDK对象 EncdbSDK build();
EncdbSDK
即com.alibaba.encdb.EncdbSDK
。使用中您需要以下API:// 获取一个Cryptor对象,用于操作密文/明文。 Cryptor getCryptor();
Cryptor
即com.alibaba.encdb.Cryptor
。使用中您需要以下API:// 输入密文,返回对应的明文 byte[] decrypt(byte[] val);