配置步骤(非安全增强型实例)
本文介绍如何在非Intel SGX 增强型实例中配置和使用全加密云数据库功能。
前提条件
RDS PostgreSQL服务端
已创建云数据库RDS PostgreSQL 10或以上版本的实例,创建方式请参见快速创建RDS PostgreSQL实例。
已获取RDS PostgreSQL实例的内外网地址,获取方式请参见查看内外网地址。
已创建数据库高权限账号,创建方式请参见创建账号。
本地客户端
本文示例代码使用的开发语言为Java,请确保已具备Java开发环境,建议使用Java版本为
1.8
及以上,使用的开发工具为IntelliJ IDEA Community Edition 2022.3.2
。已根据服务端版本下载对应EncDB依赖包。
RDS PostgreSQL小版本
服务端encdb插件版本号
客户端EncDB依赖包
20210531
1.1.5
20210930
1.1.6
20211031 ~ 20220130
1.1.7
20220228 ~ 20220730
1.1.9
20220830 ~ 20221030
说明RDS PostgreSQL 15在20221030内核版本时,配套插件版本为1.1.12。
1.1.11
20221230或以上版本
1.1.12
已生成用户主密钥。
用户主密钥由长度为16字节的16进制字符串组成,本示例以
0x00112233445566778899aabbccddeeff
为例。常见的生成方法有:密码生成工具(如openssl,openssl rand -hex 16
)、编程语言中的random函数。警告用户主密钥是您访问加密数据的根凭据,全加密功能不提供用户主密钥的生成和备份服务,您需要自行生成用户主密钥。一旦您丢失密钥,将无法再访问已有的数据。因此我们建议您妥善备份用户主密钥。
背景信息
在RDS PostgreSQL的非Intel SGX 安全增强型规格实例上,全加密功能可以利用密码学方法提供数据安全保护,但支持的操作类型较少,具体请参见功能支持。
RDS PostgreSQL 10或其以上版本的所有实例规格都支持全加密功能,但推荐您选择Intel SGX 安全增强型规格,以获得最完整的全加密功能支持。安全增强型规格的配置步骤,请参见配置步骤(安全增强型实例)。
本文以非Intel SGX 安全增强型规格的PostgreSQL实例为例,介绍如何通过客户端连接并使用全加密云数据库。
服务端配置步骤
全加密云数据库在RDS PostgreSQL服务端以扩展(Extension)形式部署。本步骤介绍如何在服务器端安装扩展以及创建加密表。
本步骤需要连接RDS PostgreSQL实例进行操作,连接方法请参见连接PostgreSQL实例。
安装EncDB扩展。
CREATE EXTENSION encdb;
创建加密表。
创建加密表时,您可以根据自身需要,将敏感字段的数据类型替换为对应的加密数据类型。以下表为例,其原始定义如下:
CREATE TABLE example ( id INTEGER, name VARCHAR, price INTEGER, miles REAL, secret TEXT, PRIMARY KEY (id) );
如果选择price,miles,secret为敏感数据,创建的加密表定义如下:
CREATE TABLE example ( id INTEGER, name VARCHAR, price rnd_type, miles det_type, secret rnd_type, PRIMARY KEY (id) );
说明非Intel SGX 增强型实例中,全加密数据库功能目前支持det_type和rnd_type两种加密数据类型。其中det_type为确定性加密(同一个敏感数据两次加密得到的密文相同),rnd_type为不确定性加密 (同一个敏感数据两次加密得到的密文不同)。
当您在应用程序中使用det_type和rnd_type时,需要将全加密数据库det_type和rnd_type对应的宿主变量转换为string数据类型。
您不能直接修改原有表(即
ALTER TABLE
),而是需要新建一个加密表,然后再将原表数据通过SDK加密后导入。
客户端配置步骤
本步骤介绍客户端如何连接数据库并进行数据加密解密操作。
本示例以Maven构建Java项目为例。
安装EncDB依赖包。
mvn install:install-file -DgroupId=com.alibaba.encdb -DartifactId=<安装的Jar包名> -Dversion=<安装的Jar版本> -Dpackaging=jar -Dfile=<下载的Jar包所在路径>/<安装的Jar包名.jar>
示例:
mvn install:install-file -DgroupId=com.alibaba.encdb -DartifactId=libencdb -Dversion=1.2.12 -Dpackaging=jar -Dfile=D:\encdb\libs\libencdb-1.2.12.jar
说明此示例中EncDB依赖包在D:\encdb\libs路径下。
此示例使用的Maven版本为
3.9.2
,如果您安装报错,请升级Maven版本后再试。
添加依赖。
您需要在pom.xml中添加如下依赖:
<dependencies> ... <dependency> <groupId>com.alibaba.encdb</groupId> <artifactId>libencdb</artifactId> <version>1.2.12</version> </dependency> <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</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>31.1-jre</version> </dependency> ... </dependencies>
全加密功能使用示例。
连接数据库。
说明此示例中MEK仅为测试用,实际应用中请使用自己的MEK。参数Mek和EncAlgo只作为EncDB SDK的加解密模块使用,不会直接传送给服务器端。
try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } String hostname = "pgm-uf6qw1ap115gr2****.pg.rds.aliyuncs.com"; String port = "5432"; String dbname = "encdbtest"; String username = "username"; String password = "userpassword"; String tableName = "example"; String mek = "0x00112233445566778899aabbccddeeff"; String dbUrl = "jdbc:postgresql://" + hostname + ":" + port + "/" + dbname + "?binaryTransfer=true"; try { dbConnection = DriverManager.getConnection(dbUrl, username, password); } catch (SQLException throwables) { throwables.printStackTrace(); } /*创建EncdbSDK实例*/ EncdbSDK sdk = EncdbSDKBuilder.newInstance() .setDbConnection(dbConnection) .setMek(mek) .setEncAlgo(Constants.EncAlgo.SM4_128_CBC) .setDekGenMode(Constants.DekGenMode.LOCAL) .setSdkMode(Constants.SDKMode.Crypto) .build(); Cryptor crypto = sdk.getCryptor();
上述示例中关键参数解释及取值示例如下:
参数
取值示例(字符串类型)
说明
Mek
0x00112233445566778899aabbccddeeff
用户主密钥。
取值范围:长度为16字节的16进制字符串。
EncAlgo
SM4_128_CBC
加密算法。
取值范围:
AES_128_GCM
AES_128_CBC
SM4_128_CBC(默认值)
DekGenMode
LOCAL
生成数据密钥的方式。固定为LOCAL,不能修改。
SdkMode
Crypto
SDK模式。固定为Crypto,不能修改。
插入加密数据。
PreparedStatement stmt = dbConnection.prepareStatement("insert into " + tableName + " (id, name, price, miles, secret) values(?,?,?,?,?)"); int price = 1234; float miles = 12.34f; String secret = "aliyun"; stmt.setInt(1, 1); stmt.setString(2, "name"); stmt.setBytes(3, crypto.encrypt(tableName, "price", String.valueOf(price))); stmt.setBytes(4, crypto.encrypt(tableName, "miles", String.valueOf(miles))); stmt.setBytes(5, crypto.encrypt(tableName, "secret", secret)); stmt.execute();
查询解密数据。
String sqlCmd = "SELECT * from " + tableName + " where miles = ?"; PreparedStatement stmt = dbConnection.prepareStatement(sqlCmd); stmt.setBytes(1, crypto.encrypt(tableName, "miles", "12.34")); ResultSet rs = stmt.executeQuery(); while (rs.next()) { int id = rs.getInt(1); String name = rs.getString(2); int price = Integer.parseInt(crypto.decryptString(rs.getBytes(3))); float miles = Float.parseFloat(crypto.decryptString(rs.getBytes(4))); String text = crypto.decryptString(rs.getBytes(5)); System.out.println(id + ", " + name + ", " + price + ", " + miles + ", " + text); }
查询结果:
已加密的数据在客户端查询时被解密,您可以查询到明文。
1, name, 1234, 12.34, aliyun
已被加密的数据在服务器端无法查看,能够有效防御来自云平台外部和内部的安全威胁,时刻保护用户数据。
select * from example;
id | name | price | miles | secret ----+------+--------------------------------------------------------------------------+--------------------------------------------------------------------------+-------------------------------------------------------------------------- 1 | name | \xdf4901df087c6a3e0325175bb76942c684191a8dda2a8d0c35f295dc1e30eaeaa0c0e3 | \x315102ea5ab8a659066ab672e6dfbfd89a3a2b360bf6efe3787931e00f61af05f7408c | \xed4903dfd1bda1a89ad6aa7e8905c0e6305e15db4bc9ce2d2cfac9e25094d2a3ed367d (1 行记录)