【问题标题】:Oracle data maskingOracle 数据屏蔽
【发布时间】:2014-03-21 06:04:01
【问题描述】:

我们有一个要求,即使用 Oracle 函数屏蔽特定的表列,该函数提供持久的屏蔽输出字符串。

  • 我们尝试了 Oracle 哈希函数,但它没有给出字符串类型的返回值。
  • 我们尝试了 Oracle Random 函数 (dbms_random.string),但它没有给出 Persistent 输出字符串。

我在互联网上读到这称为确定性掩码。但是我们不想使用 Oracle Enterprise Manager;但是我们需要一个直接的 Oracle 函数。

请提出建议。

【问题讨论】:

  • 不要认为有一个内置的 Oracle 函数可以解决这个问题。相信您将需要为此创建一个包或 pl/sql 块,以用屏蔽值替换敏感信息。您可以使用 Regexp_Replace 根据模式替换值。
  • Oracle 提供数据屏蔽包,但这不是免费的,需要额外的许可费用。链接到最新版本可以做什么:oracle.com/technetwork/database/manageability/…

标签: oracle oracle11g masking data-masking


【解决方案1】:

这个问题在 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);

让我惊讶的是有多少产品和工具可以做这么简单的事情。

【讨论】:

  • +1 用于工作解决方案。但我想问我们如何使用该函数来更新表格?
  • @AloneInTheDark 我在答案中添加了更多信息。
  • @OliverStutz 我刚刚用 SHA512 试了一下,它就像官方功能一样工作。尽管我最初的答案没有包括授予对 DBMS_CRYPTO 包的访问权限的步骤。这可能会导致问题,所以我将其添加到我的答案中。
  • @JonHeller 问题是在 11g 中,包中没有超过 SHA-1 的哈希值!
  • @OliverStutz 你是对的,我没有注意到,因为我只在 11g 上测试。我添加了 PL/SQL 条件编译,因此更现代的加密函数不包含在 11g 中。我刚刚对其进行了测试,它现在应该可以在 11g 上运行,但仅适用于 MD5 和 SHA1。
【解决方案2】:

如果您希望屏蔽生产数据以将其移至非生产数据以进行集成测试。下面的“用户定义”功能将对您有所帮助。此功能仅适用于 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;    

【讨论】:

  • 这个功能有一些问题。它不必要地使用 SQL,这将导致许多上下文切换和性能不佳。而且它不是确定性的,相同的输入不会总是产生相同的输出。它可能存在一些密码问题。
  • 你能详细解释一下它是如何“上下文切换和性能差”的,因为它是直接在双重查询中的。此函数的主要目的不是创建相同的输出。
  • PL/SQL 调用 SQL 时都会产生开销。 select ... from dual; 可以替换为 PL/SQL 赋值语句 variable := ...;
【解决方案3】:

在 Oracle 12C 中,dbms_redact.add_policy 可用。它可用于在选择查询本身中获取掩码值。

【讨论】:

    【解决方案4】:

    可以使用 oracle 的 dbms_crpyto 包,首先需要将 varchar2 类型转换为 raw,然后根据哈希值屏蔽数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      相关资源
      最近更新 更多