我们有一个要求是使用一个 Oracle 函数来屏蔽一个特定的表列,该函数提供持久的屏蔽输出字符串。
- 我们尝试了 Oracle 哈希函数,但它没有给出字符串类型的返回值。
- 我们尝试了 Oracle Random 函数 (dbms_random.string),但它没有给出持久输出字符串。
我在互联网上读到这被称为确定性掩蔽。但是我们不想使用 Oracle Enterprise Manager;但是我们需要一个直接的 Oracle 函数。
请建议。
我们有一个要求是使用一个 Oracle 函数来屏蔽一个特定的表列,该函数提供持久的屏蔽输出字符串。
我在互联网上读到这被称为确定性掩蔽。但是我们不想使用 Oracle Enterprise Manager;但是我们需要一个直接的 Oracle 函数。
请建议。
这个问题在 12c 中很容易通过函数STANDARD_HASH解决。
以前版本中的解决方案只是稍微复杂一些。围绕 DBMS_CRYPTO 构建一个简单的包装器,其作用类似于 STANDARD_HASH:
--Imitation of the 12c function with the same name.
--Remember to drop this function when you upgrade!
create or replace function standard_hash(
p_string varchar2,
p_method varchar2 default 'SHA1'
) return varchar2 is
v_method number;
v_invalid_identifier exception;
pragma exception_init(v_invalid_identifier, -904);
begin
--Intentionally case-sensitive, just like the 12c version.
if p_method = 'SHA1' then
v_method := dbms_crypto.hash_sh1;
--These algorithms are only available in 12c and above.
$IF NOT DBMS_DB_VERSION.VER_LE_11 $THEN
elsif p_method = 'SHA256' then
v_method := dbms_crypto.hash_sh256;
elsif p_method = 'SHA384' then
v_method := dbms_crypto.hash_sh384;
elsif p_method = 'SHA512' then
v_method := dbms_crypto.hash_sh512;
$END
elsif p_method = 'MD5' then
v_method := dbms_crypto.hash_md5;
else
raise v_invalid_identifier;
end if;
return rawToHex(dbms_crypto.hash(utl_raw.cast_to_raw(p_string), v_method));
end;
/
您可能需要使用 SYS 登录并授予您的用户对 DBMS_CRYPTO 的访问权限以使该功能正常工作:
grant execute on sys.dbms_crypto to <your_schema>;
创建一个公共同义词,将其授予每个人,它的工作方式完全相同。
create public synonym standard_hash for <schema with function>.standard_hash;
grant execute on standard_hash to public;
select standard_hash('Some text', 'MD5') from dual;
9DB5682A4D778CA2CB79580BDB67083F
select standard_hash('Some text', 'md5') from dual;
ORA-00904: : invalid identifier
下面是一个使用该函数的简单示例:
update some_table
set column1 = standard_hash(column1),
column2 = standard_hash(column2);
但是更新大量数据可能会很慢。创建新表、删除旧表、重命名新表等可能会更快。并且哈希值可能大于列大小,可能需要alter table some_table modify column1 varchar2(40 byte);
让我惊讶的是有多少产品和工具可以做这么简单的事情。
如果您看起来像屏蔽生产数据以将其移动到非产品以进行集成测试。下面的“用户定义”功能将对您有所帮助。此功能仅适用于 10G 及以上。
create or replace function scrubbing(word in varchar2)
return varchar2
as
each_var char(2);
final_val varchar2(100);
complete_data varchar2(4000);
each_word varchar2(1000);
cursor val is select substr(replace(word,' ','#'),-level,1) from dual connect by level<=length(word);
begin
open val;
--final_val:= '';
loop
fetch val into each_var;
exit when val%NOTFOUND;
--dbms_output.put_line(each_var);
final_val := trim(final_val)||trim(each_var);
--dbms_output.put_line(final_val);
select regexp_substr(final_val,'[A-Za-z]+') into each_word from dual;
select replace(translate(final_val,each_word,dbms_random.string('L',length(word))),'#',' ') into complete_data from dual;
end loop;
return complete_data;
end;
在 Oracle 12C 中,dbms_redact.add_policy 可用。它可用于获取选择查询本身中的屏蔽值。
您可以使用 oracle 的 dbms_crpyto 包,首先您需要将 varchar2 类型转换为 raw 然后根据哈希值屏蔽数据。