本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
若需通过Java应用程序访问数据库中的加密列数据,您可以使用阿里云提供的列加密驱动(JDBC)。在持有用户密钥的情况下,列加密驱动能够自动完成密文数据的解密并返回明文数据,该过程对应用程序是透明的。应用程序只需配置几行代码,即可接入列加密能力。
前提条件
已开通列加密,详情请参见列加密。
开通列加密后,系统将默认在目标数据库中安装rds_encdb插件。您可以通过执行SQL语句来查询rds_encdb插件的状态:
SELECT EXISTS (SELECT * FROM pg_extension WHERE extname = 'rds_encdb');
已获取加密数据库连接信息。您首先需要获取加密数据库的连接信息,如域名(host)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等。实例内网或外网地址获取方式请参见查看或修改连接地址和端口。
已为数据库用户配置了列加密的密文权限(JDBC解密),详情请参见修改数据库账号权限。
注意事项
请保存好您设置的主密钥
MEK
。Java使用JDK 1.8或以上版本。
操作步骤
本文以Maven构建Java项目为例。
步骤一:配置Maven依赖
在Maven项目的pom.xml配置文件中加入以下依赖项。
<dependencies>
...
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-cls-jdbc</artifactId>
<version>1.0.10-1</version>
</dependency>
...
</dependencies>
步骤二:配置URL和MEK
通过JDBC访问数据库加密列的数据前,需要配置相关参数,包括MEK
(主密钥)、URL
(数据库连接信息)。
参数 | 取值示例(字符串类型) | 说明 |
参数 | 取值示例(字符串类型) | 说明 |
MEK | 00112233445566778899aabbccddeeff | 用户主密钥,由用户自定义。
用户主密钥是您访问加密数据的根凭据,出于安全考虑,数据库不持有并管理您的主密钥,也不提供用户主密钥的生成和备份服务,您需要自行生成用户主密钥。一旦您丢失密钥,将无法再访问已有的数据。因此我们建议您妥善备份用户主密钥。 |
URL | jdbc:postgresql:encdb://%s:%s/%s | 使用列加密驱动时,请将URL修改为以 |
配置MEK
以下将介绍三种配置MEK
的方法。如果您的JDBC同时配置了两种以上的方式,优先级顺序为:JDBC properties配置 > 文件配置 > URL配置。
URL配置方式中,多个参数可以用
&
进行拼接。以下三种连接方式,
MEK
均在客户端本地进行处理、并以安全方式分发(信封加密)到服务端,始终保证MEK
不泄露。
标准的JDBC在建立连接时,可以通过Properties配置用户自定义属性。例如:
// 准备好域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息
// ...
String mek=****;
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", mek);
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
Connection connection = DriverManager.getConnection(dbUrl, props);
// ... 发起查询 ...
支持通过配置文件导入所需的参数,例如MEK
。在项目中设置一个名为encJdbcConfigFile
的属性,将其值指定为配置文件的路径。若未设置,该属性将默认使用 encjdbc.conf
文件。
配置文件的内容如下:
MEK=****
您可以通过以下两种方式放置配置文件的位置:
将文件放入项目中的resources目录下,如下图所示:
将文件放入项目根目录,即程序的运行时目录。
通过文件配置MEK后,程序中无需额外配置,例如:
// 准备好域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息
// ...
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... 发起查询 ...
支持通过URL链接中嵌入MEK
、ENC_ALGO
等参数。如下面所示:
// 准备好域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息
// ...
String mek=****;
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s?MEK=%s", hostname, port, dbname, mek);
Connection connection = DriverManager.getConnection(dbUrl, username, password);
// ... 发起查询 ...
完整示例代码
如下示例代码以JDBC properties配置MEK
的方式为例。在进行JDBC访问之前,已完成目标数据库的列加密设置。
package org.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class Main {
public static void main(String[] args) throws SQLException {
// 以下连接信息(hostname、port、dbname、username、password)需要根据实际情况更新
String hostname = "pgm-****.pg.rds.aliyuncs.com"; // 实例连接地址,请更新为实际值
String port = "5432"; // 数据库端口,请更新为实际值
String dbname = "testdb"; // 数据库名称,请更新为实际值
String username = "user"; // 数据库用户名,请更新为实际具有密文权限(JDBC解密)的用户
String password = "password"; // 数据库用户名的密码
// 示例密钥,建议使用复杂度更高的密钥以确保安全
String MEK = "00112233445566778899aabbccddeeff";
// 创建数据库连接属性
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("MEK", MEK);
// 格式化数据库连接URL
String dbUrl = String.format("jdbc:postgresql:encdb://%s:%s/%s", hostname, port, dbname);
// 使用DriverManager获取数据库连接
Connection connection = DriverManager.getConnection(dbUrl, props);
// 执行查询以获取测试表中的数据
ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM test_table");
while (rs.next()) {
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { // 列索引从1开始
System.out.print(rs.getString(i) + "\t");
}
System.out.println(); // 换行
}
// 关闭资源
rs.close(); // 关闭结果集
connection.close(); // 关闭连接
}
}
- 本页导读
- 前提条件
- 注意事项
- 操作步骤
- 步骤一:配置Maven依赖
- 步骤二:配置URL和MEK
- 完整示例代码