最佳实践

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

RDS MySQL全密态数据库能够对数据库查询结果中的数据进行加密和脱敏保护,任何非授权人员均无法查看被保护数据明文内容。本文介绍如何通过全密态客户端驱动EncJDBC快速使用并验证RDS MySQL全密态数据库功能。

前提条件

RDS MySQL实例的大版本为MySQL 5.7,且内核小版本必须大于或等于20231215。

说明

升级内核小版,请参见升级内核小版本

注意事项

  • 请妥善保存您设置的主密钥MEK

  • Java版本需要在1.8及以上。

    说明

    本文中使用的Maven版本为3.9.5,使用的开发工具为IntelliJ IDEA Community Edition 2023.2.4

操作步骤

步骤一: 创建实例、数据库及账号

  1. 购买符合本文前提条件的RDS MySQL实例,创建方法请参见创建RDS MySQL实例RDS MySQL标准版(原X86)主实例规格列表RDS MySQL经济版(原ARM)主实例规格列表

    说明

    如果您已购实例已满足本文前提条件中的要求,则无需新购实例。

  2. 创建数据库高权限账号,创建方法请参见创建账号

  3. 创建数据库,详情请参见管理数据库

步骤二: 开启全密态功能

  1. 访问RDS实例列表,在上方选择地域,单击刚刚创建的实例ID。

  2. 开通全密态功能。

    警告

    开通全密态功能会导致实例重启,请在业务低峰期操作。

    在左侧导航栏,单击参数设置,在可修改参数页签,搜索loose_encdb,将该参数值设置为ON,选择生效时间后,单击确定

步骤三: 配置数据保护规则

说明

开通全密态功能以及配置数据保护规则的账号必须是高权限账号。应用数据库角色建议设为普通权限,不具备管理员权限,且不建议赋予应用数据库角色高权限。

  1. 确定被保护字段

    用户基于业务实际需要,确定哪些数据属于被保护数据。本文示例中,将通讯录中的部门名称(department.name)、员工姓名(users.name)和ID(users.id)确定为被保护数据。数据库表结构如下:

    说明

    建表之前需要先执行CREATE DATABASE contact;创建contact数据库。

    -- 部门表
    CREATE TABLE department (id INTEGER PRIMARY KEY AUTO_INCREMENT, dept_id BIGINT, name TEXT, parentId BIGINT, createDeptGroup BOOL, autoAddUser BOOL, UNIQUE(dept_id));
    -- 用户表
    CREATE TABLE users (id varchar(255) PRIMARY KEY, dept_id BIGINT, name TEXT, avatar TEXT);
    
    -- 写入测试数据
    INSERT INTO department(dept_id, name, parentId, createDeptGroup, autoAddUser) VALUES
     (202301,'dept1',202301,true,true), (202302,'dept2',202301,true,true), (202303,'dept3',202301,true,false);
    INSERT INTO users VALUES
     ('110110181103233433', 202301, 'user1', 'director'),
     ('350110180103038669', 202302, 'user2', 'dept2_user'), ('220110182203032387', 202302, 'user3', 'dept2_user'),
     ('410110182209237752', 202303, 'user4', 'dept3_user'), ('310140181210228325', 202303, 'user5', 'dept3_user');
  2. 配置规则

    基于选定的被保护数据,按照数据保护规则格式,编辑规则内容,并通过SQL UDF下发规则。更多规则格式介绍请参见数据保护规则简介

    SELECT encdb_rule_op('add', '[{
                                   "name": "rule-for-contact-name",
                                   "enabled": true,
                                   "meta": {
                                     "databases": ["contact"],
                                     "tables": ["department","users"],
                                     "columns": ["name"]
                                   }
                                  }, {
                                   "name": "rule-for-contact-id",
                                   "enabled": true,
                                   "meta": {
                                     "databases": ["contact"],
                                     "tables": ["users"],
                                     "columns": ["id"]
                                   }
                                  }]');

    其中,rule-for-contact-name同时标记了部门名称(department.name)以及员工姓名(users.name),rule-for-contact-id标记了员工ID(users.id)。

  3. 授权用户访问

    若希望数据库用户在应用客户端侧能够访问解密后的明文结果,需要为其授予受限访问权限(restrictedAccess)。更多授权信息,请参见配置数据保护规则

    执行如下命令,授权应用数据库角色受限访问权限:

    SELECT encdb_rule_op('grant','{"restrictedAccess": ["appuser"]}'); 
    说明

    appuser为应用数据库角色。

步骤四: 客户端接入改造

全密态数据库提供了配套的数据库连接驱动,无需修改业务代码,应用客户端侧仅需进行如下两步配置,就能够无感访问全密态数据库。本步骤以EncJDBC接入为例进行说明:

  1. 将数据库连接驱动替换成EncJDBC

  2. 更新数据库连接URL,指定用户密钥MEK以及加密算法ENC_ALGO

以Java语言为例,仅需如下两处配置修改即可:

// 准备好域名(hostname)、端口(port)、数据库实例名(dbname)、用户名(username)、密码(password)等连接信息
// ...
String mek="00112233445566778899aabbccddeeff";
String encAlgo="SM4_128_CTR";

// 1. 将数据库连接驱动替换成EncJDBC
Class.forName("com.aliyun.encdb.mysql.jdbc.EncDriver");
// 2. 更新数据库连接URL,指定用户密钥MEK以及加密算法ENC_ALGO
String dbUrl = String.format("jdbc:mysql:encdb://%s:%s/%s?MEK=%s&ENC_ALGO=%s", hostname, port, dbname, mek, encAlgo);

java.sql.Connection connection = java.sql.DriverManager.getConnection(dbUrl, username, password);
// ... 发起查询 ...

更多客户端EncJDBC接入配置请参见EncJDBC

步骤五: 功能验证

可以在命令行工具或者DMS控制台上,执行SQL命令验证数据是否被加密保护:

  • 执行如下命令查询通讯录指定的部门信息:

    SELECT * FROM contact.department WHERE dept_id = 202302;

    查询结果如下:

    image.png

  • 执行如下命令查询通讯录指定部门的员工信息:

    SELECT * FROM contact.users WHERE dept_id = 202302;

    查询结果如下:

    image.png

  • 执行如下命令模糊查询通讯录员工信息:

    SELECT * FROM contact.users WHERE name LIKE '%1';

    查询结果如下:

    image.png

从全密态数据库中查询的结果显示,所有被保护数据均被加密保护。

相关文档