达梦数据库的存储加密主要分为三种模式,它们分别适用于不同的业务场景和安全需求:
透明加密:这是最常用的模式。它对应用程序完全透明,用户无需修改任何代码。数据在写入磁盘时自动加密,读取时自动解密。它主要针对“数据文件被盗”的场景,保护静态数据。
半透明加密:这是一种细粒度的加密方式,通常针对特定的列。它支持“谁写入,谁解密”的用户隔离机制,或者通过指定可见用户列表来控制访问权限。非可见用户查询时,数据将显示为NULL。
非透明加密:这种模式下,加密和解密需要用户显式调用加密函数。它提供了最高的灵活性,但需要应用程序配合修改。
环境准备与算法选择
我们需要了解当前数据库实例支持的加密算法。达梦数据库支持国密算法(如SM4)以及国际标准算法(如AES)。
特性 透明加密 半透明加密 非透明加密
加解密主体 数据库系统自动完成 数据库系统自动完成 应用层通过加密引擎接口完成
用户感知 完全透明,无感知 透明,但受 UID 权限控制 应用层需显式调用加解密函数
适用场景 防止物理文件泄露、合规审计 防止用户之间互相窥探、多租户隔离 极高安全性要求,需应用层完全掌控密钥
性能开销 中(全库/表空间级)至低(列级) 中(涉及 UID 校验) 低(通常在客户端处理)
密钥管理 系统主密钥 (SVR_KEY/DB_KEY) 用户存储加密密钥 应用自定义密钥
-- 查看当前版本支持的加密算法
SELECT * FROM V$CIPHERS;
-- 查看外部加密算法支持情况(如配置了KMS或第三方库)
SELECT * FROM V$EXTERNAL_CIPHERS;
透明加密是保护整体数据文件最有效的手段。我们可以创建一个加密表空间,并将敏感业务表存放在其中。
步骤 1:创建加密表空间
以下SQL展示如何创建一个使用AES128算法加密的表空间:
1-- 创建加密表空间 TESTBKJ
2-- 注意:ENCRYPT WITH 指定算法,BY 指定密钥(Test_1234)
3CREATE TABLESPACE "TESTBKJ"
4DATAFILE 'TESTBKJ.DBF' SIZE 1024
5AUTOEXTEND ON NEXT 100 MAXSIZE 10240
6CACHE = NORMAL
7ENCRYPT WITH AES128_CBC_NOPAD BY "Test_1234";
步骤 2:验证表空间属性
创建完成后,我们可以通过管理工具或查询视图确认加密状态:
步骤 3:数据落地
一旦创建了加密用户并指定默认表空间为TESTBKJ,该用户创建的所有表数据在物理磁盘上都会自动加密。
-- 创建用户并指定默认表空间
CREATE USER "SEC_USER" IDENTIFIED BY "SecurePass123"
DEFAULT TABLESPACE "TESTBKJ";
GRANT RESOURCE, PUBLIC TO "SEC_USER";
-- 用户登录建表,数据自动加密
CREATE TABLE SECRET_DATA (ID INT, CONTENT VARCHAR(100));
INSERT INTO SECRET_DATA VALUES (1, '绝密信息');
COMMIT;
对于某些核心字段(如身份证号、手机号),我们可能不希望DBA或普通应用账号直接查看明文。半透明加密提供了列级的访问控制。
特性注意:
步骤 1:创建包含半透明加密列的表
-- 创建测试表,C2列进行半透明加密
-- MANUAL 关键字表示手动管理加密属性
CREATE TABLE TEST_SEMI_ENCRYPT (
C1 INT,
C2 VARCHAR(50) ENCRYPT MANUAL
);
步骤 2:用户隔离测试
半透明加密的一个核心特性是用户隔离。让我们模拟用户A写入数据,用户B尝试读取的场景。
-- 1. 创建两个测试用户
CREATE USER USER_A IDENTIFIED BY "Test_1234";
CREATE USER USER_B IDENTIFIED BY "Test_1234";
GRANT DBA TO USER_A;
GRANT DBA TO USER_B;
-- 2. 用户A插入数据
INSERT INTO SYSDBA.TEST_SEMI_ENCRYPT (C1, C2) VALUES (1, '用户A的隐私');
COMMIT;
-- 3. 用户B尝试查询
SELECT * FROM SYSDBA.TEST_SEMI_ENCRYPT;
预期结果:用户B查询时,C2列的内容将显示为NULL,因为该列是半透明加密的,且由用户A写入,用户B没有解密权限。
除了基本的半透明加密,达梦还支持更高级的“按列加密”选项,允许指定特定的密钥和可见用户列表。
-- 创建表并指定列加密选项
-- 使用指定的密钥进行加密,并仅对特定用户可见
CREATE TABLE TEST_ADV_ENCRYPT (
ID INT,
SENSITIVE_INFO VARCHAR(100)
ENCRYPT WITH DES_ECB MANUAL HASH WITH MD5 SALT
达梦数据库提供了一系列内置函数,支持对 VARCHAR、VARBINARY、DATE、DEC 等多种数据类型进行加密。
核心特点:
应用层控制: 密钥掌握在应用手中,数据库只负责存储密文。
高安全性: 即使数据文件被盗,没有密钥也无法还原数据。
灵活性: 可以针对特定字段进行细粒度的加密处理。
常用函数列表<具体可参考存储加密>:
功能 函数名称 适用数据类型 返回值类型
通用加密 CFALGORITHMSENCRYPT VARCHAR/TEXT/CLOB 同输入类型
通用解密 CFALGORITHMSDECRYPT VARCHAR/TEXT/CLOB 同输入类型
字符加密 SF_ENCRYPT_CHAR VARCHAR VARBINARY
字符解密 SF_DECRYPT_TO_CHAR VARBINARY VARCHAR
日期加密 SF_ENCRYPT_DATE DATE VARBINARY
数值加密 SF_ENCRYPT_DEC DEC VARBINARY
二进制加密 SF_ENCRYPT_BINARY VARBINARY VARBINARY
xxxxxxx xxxxx xxxxxxx xxxxxxx
...
这是最基础的用法,适用于大多数文本数据的加密。
5.1.1创建测试表
由于 CFALGORITHMSENCRYPT 返回的密文长度通常会变长,建议字段长度设置得比明文大。
CREATE TABLE user_info ((
id INT IDENTITY(1,1),
username VARCHAR(50),
phone_num VARCHAR(200);) -- 存储加密后的手机号
5.1.2插入加密数据
我们使用密钥 'MySecretKey123' 对手机号进行加密。
INSERT INTO user_info (username, phone_num)
VALUES (('张三', CFALGORITHMSENCRYPT('13800138000', 514, 'MySecretKey123')));
INSERT INTO user_info (username, phone_num)
VALUES (('李四', CFALGORITHMSENCRYPT('13900139000', 514, 'MySecretKey123')));
COMMIT;
5.2查看存储的密文
直接查询表,DBA 或普通用户只能看到乱码。
5.3业务层解密查询
当应用程序需要展示数据时,调用解密函数。
SELECT
id,
username,
CFALGORITHMSDECRYPT(phone_num, 514, 'MySecretKey123') AS real_phone
FROM user_info;
对于日期和金额字段,使用专用的加密函数可以保持数据类型的对应关系,方便后续处理。
5.2.1创建包含敏感数据的表
CREATE TABLE employee_salary (
emp_id INT,
hire_date_enc VARBINARY(200), -- 存储加密后的入职日期
salary_enc VARBINARY(200;) -- 存储加密后的薪资.
5.2.2插入加密数据
-- 加密日期
INSERT INTO employee_salary
(VALUES (101, SF_ENCRYPT_DATE(cast('2011-1-1' as date), 514, '仅供测试使用',NULL),
SF_ENCRYPT_DEC(CAST(15000.00 AS DEC(10,2)), 514, 'SalaryKey',NULL)));
COMMIT;.
5.2.3 解密还原数据
SELECT
emp_id,
SF_DECRYPT_TO_DATE(hire_date_enc, 514, '仅供测试使用',NULL) AS hire_date,
SF_DECRYPT_TO_DEC(salary_enc, 514, 'SalaryKey',NULL) AS salary
FROM employee_salary;
文章
阅读量
获赞
