Oracle Data Redaction(数据脱敏)
Oracle Data Redaction(数据脱敏)
适用版本:Oracle Database 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
Oracle Data Redaction(数据脱敏) 是 12c 引入的特性[1],对查询结果实时脱敏:
核心特性:
- 应用透明:无需修改应用
- 实时脱敏:查询时脱敏
- 基于策略:用户/时间/IP 等条件
- 多种脱敏方式:完全/部分/正则/随机
典型场景:
- 客服查看用户信息
- 应用日志脱敏
- 测试数据脱敏
2. 脱敏策略类型
2.1 完全脱敏(Full Redaction)
-- 数字返回 0
-- 字符返回空格
-- 日期返回 01-JAN-01
2.2 部分脱敏(Partial Redaction)
-- 信用卡号: ****-****-****-1234
-- 身份证号: 110***********1234
2.3 正则脱敏(Regular Expression)
-- 邮箱: a***@example.com
-- 电话: 138****1234
2.4 随机脱敏(Random)
-- 每次返回不同的随机值
3. 配置完全脱敏
3.1 创建策略
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'employees',
policy_name => 'redact_ssn',
column_name => 'ssn',
function_type => DBMS_REDACT.FULL,
expression => '1=1'
);
END;
/
3.2 测试
-- 原始数据
SELECT ssn FROM scott.employees WHERE id = 1;
-- 返回: ' ' (空格)
-- 普通用户看到的
SELECT ssn FROM scott.employees;
-- 所有 ssn 都是空格
-- SYS 用户看到的
SELECT ssn FROM scott.employees;
-- 真实数据(SYS 绕过脱敏)
4. 配置部分脱敏
4.1 信用卡号脱敏
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_credit_card',
column_name => 'credit_card',
function_type => DBMS_REDACT.PARTIAL,
function_parameters => 'VVVVFVVVVFVVVVFVVVV,VVVV-VVVV-VVVV-VVVV,*,1,12',
expression => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') != ''APP_ADMIN'''
);
END;
/
4.2 参数说明
function_parameters: 'input_format,output_format,mask_char,start_pos,end_pos'
- input_format: 输入格式(V=字符,F=固定分隔符)
- output_format: 输出格式
- mask_char: 脱敏字符
- start_pos: 脱敏起始位置
- end_pos: 脱敏结束位置
4.3 身份证号脱敏
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_id',
column_name => 'id_card',
function_type => DBMS_REDACT.PARTIAL,
function_parameters => 'VVVVVVVVVVVVVVVVVVV,*,1,6,14',
expression => '1=1'
);
END;
/
5. 正则脱敏
5.1 邮箱脱敏
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_email',
column_name => 'email',
function_type => DBMS_REDACT.REGEXP,
function_parameters => 'REGEXP_REPLACE(email, ''([^@]+)@(.*)'', ''\1****@\2'')',
expression => '1=1'
);
END;
/
5.2 电话号码脱敏
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_phone',
column_name => 'phone',
function_type => DBMS_REDACT.REGEXP,
function_parameters => 'REGEXP_REPLACE(phone, ''(\d{3})\d{4}(\d{4})'', ''\1****\2'')',
expression => '1=1'
);
END;
/
6. 随机脱敏
6.1 数字随机
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'employees',
policy_name => 'redact_salary',
column_name => 'salary',
function_type => DBMS_REDACT.RANDOM,
expression => '1=1'
);
END;
/
6.2 字符随机
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'employees',
policy_name => 'redact_name',
column_name => 'name',
function_type => DBMS_REDACT.RANDOM,
expression => '1=1'
);
END;
/
7. 多列脱敏
7.1 一个策略多列
BEGIN
DBMS_REDACT.ADD_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_all',
column_name => 'ssn',
function_type => DBMS_REDACT.FULL,
expression => '1=1'
);
-- 添加更多列
DBMS_REDACT.ALTER_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_all',
action => DBMS_REDACT.ADD_COLUMN,
column_name => 'credit_card',
function_type => DBMS_REDACT.PARTIAL,
function_parameters => 'VVVVFVVVVFVVVVFVVVV,VVVV-VVVV-VVVV-VVVV,*,1,12'
);
DBMS_REDACT.ALTER_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_all',
action => DBMS_REDACT.ADD_COLUMN,
column_name => 'email',
function_type => DBMS_REDACT.REGEXP,
function_parameters => 'REGEXP_REPLACE(email, ''([^@]+)@(.*)'', ''\1****@\2'')'
);
END;
/
8. 策略条件
8.1 基于用户
expression => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') IN (''APP_USER'',''GUEST'')'
8.2 基于 IP
expression => 'SYS_CONTEXT(''USERENV'',''IP_ADDRESS'') NOT IN (''192.168.1.100'')'
8.3 基于时间
expression => 'TO_CHAR(SYSDATE, ''HH24'') BETWEEN ''18'' AND ''23'''
8.4 组合条件
expression => 'SYS_CONTEXT(''USERENV'',''SESSION_USER'') = ''APP_USER'' AND SYS_CONTEXT(''USERENV'',''IP_ADDRESS'') NOT IN (''192.168.1.100'')'
9. 策略管理
9.1 查看策略
SELECT
object_owner,
object_name,
policy_name,
column_name,
function_type,
expression
FROM dba_redaction_policies;
9.2 启用/禁用
-- 禁用
BEGIN
DBMS_REDACT.DISABLE_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_credit_card'
);
END;
/
-- 启用
BEGIN
DBMS_REDACT.ENABLE_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_credit_card'
);
END;
/
9.3 修改策略
BEGIN
DBMS_REDACT.ALTER_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_credit_card',
action => DBMS_REDACT.MODIFY_EXPRESSION,
expression => '1=1'
);
END;
/
9.4 删除策略
BEGIN
DBMS_REDACT.DROP_POLICY(
object_schema => 'scott',
object_name => 'customers',
policy_name => 'redact_credit_card'
);
END;
/
10. 监控与审计
10.1 审计脱敏操作
-- 审计 Data Redaction 策略变更
AUDIT ALTER ANY REDACTION POLICY BY ACCESS;
AUDIT CREATE REDACTION POLICY BY ACCESS;
AUDIT DROP ANY REDACTION POLICY BY ACCESS;
10.2 查看审计
SELECT
timestamp,
username,
action_name,
obj_name
FROM dba_audit_trail
WHERE action_name LIKE '%REDACTION%'
ORDER BY timestamp DESC;
11. 常见坑与排错
11.1 脱敏不生效
修复:
-- 1. 检查策略
SELECT * FROM dba_redaction_policies;
-- 2. 检查条件
SELECT expression FROM dba_redaction_policies WHERE policy_name='REDACT_CREDIT_CARD';
-- 3. 验证条件
SELECT 1 FROM dual WHERE <expression>;
11.2 ORA-28081: 权限不足
修复:
-- 需要 REDACTION_ADMIN_ROLE
GRANT REDACTION_ADMIN_ROLE TO admin_user;
11.3 SYS 用户绕过脱敏
原因:SYS/SYSDBA 默认绕过脱敏。
修复:
-- 1. 不使用 SYS 查看业务数据
-- 2. 或启用 EXEMPT REDACTION POLICY 审计
AUDIT EXEMPT REDACTION POLICY BY ACCESS;
11.4 脱敏影响索引
修复:
-- 脱敏列上的索引仍可用于过滤
-- 但返回结果是脱敏后的
-- 建议在 WHERE 条件使用真实值
SELECT * FROM customers WHERE credit_card = '1234567890123456';
-- WHERE 用真实值,SELECT 返回脱敏值
11.5 DML 失败
原因:脱敏策略可能影响 INSERT/UPDATE。
修复:
-- 确保策略仅针对 SELECT
-- 或在应用层处理
12. 最佳实践
- 敏感数据脱敏:身份证、信用卡、薪资
- 基于用户条件:仅特定用户脱敏
- 使用部分脱敏:保留部分可识别信息
- 正则脱敏:复杂格式(邮箱、电话)
- SYS 不访问业务数据:绕过脱敏
- 脱敏策略审计:监控变更
- PDB 独立策略:多租户隔离
- 结合 VPD:行级+列级防护
- 测试验证:确保脱敏生效
- 应用层配合:避免脱敏影响功能
13. 参考资料
[1] Oracle Database Advanced Security Guide 19c, “Data Redaction” https://docs.oracle.com/en/database/oracle/oracle-database/19/asoag/data-redaction.html
[2] Oracle Database Security Guide 19c, “Managing Data Redaction” https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/