如何调用Oracle的MD5哈希函数?

18

我有以下代码。我正在使用Oracle 11g。

SELECT DBMS_OBFUSCATION_TOOLKIT.md5 (input => UTL_RAW.cast_to_raw(
  FIRST_NAME
  ||LAST_NAME
  )) md5_key ,
  FIRST_NAME ,
  LAST_NAME
FROM C_NAME_TAB
WHERE PKEY='1234'

我该如何调用这段代码?我能直接在SQL开发者中执行这段代码吗?

4个回答

43

在Oracle 12c中,您可以使用函数STANDARD_HASH。它不需要任何额外的权限。

select standard_hash('foo', 'MD5') from dual;

dbms_obfuscation_toolkit已被弃用(请参见此处的说明)。您可以直接使用DBMS_CRYPTO:


select rawtohex(
    DBMS_CRYPTO.Hash (
        UTL_I18N.STRING_TO_RAW ('foo', 'AL32UTF8'),
        2)
    ) from dual;

输出:

ACBD18DB4CC2F85CEDEF654FCCC4A4D8

如有需要,请添加一个低级函数调用。更多内容请参见DBMS_CRYPTO


有没有一种方法可以解密这个密钥? - ZerOne
2
@ZerOne 不,这是一种单向哈希。请参见此处了解更多信息。 - tbone
1
由于 standard_hash 只能在 SQL 语句中调用,因此可散列的数据最大大小为 4000 字节。超出此大小的任何数据仍需要使用 dbms_crypto。 - Jared Still

5

我会做:

select DBMS_CRYPTO.HASH(rawtohex('foo') ,2) from dual;

输出:

DBMS_CRYPTO.HASH(RAWTOHEX('FOO'),2)
--------------------------------------------------------------------------------
ACBD18DB4CC2F85CEDEF654FCCC4A4D8

请注意,DBMS_CRYPTO 可能并不总是可用的,请参阅 Oracle 11g DBMS_CRYPTO invalid identifier - ckujau

4

@user755806,我认为你的问题还没有得到答复。我使用了你的代码并添加了“foo”样例字符串,加入了小写函数,并找到了哈希返回值的长度。在sqlplus或Oracle的sql developer Java数据库客户端中,你可以使用此方法调用一个值的md5sum。列格式化可以使呈现更清晰。

column hash_key format a34;
column hash_key_len format 999999;
select dbms_obfuscation_toolkit.md5(
          input => UTL_RAW.cast_to_raw('foo')) as hash_key,
       length(dbms_obfuscation_toolkit.md5(
          input => UTL_RAW.cast_to_raw('foo'))) as hash_key_len
 from dual;

结果集

HASH_KEY                           HASH_KEY_LEN
---------------------------------- ------------
acbd18db4cc2f85cedef654fccc4a4d8             32

这个值和Linux md5sum命令返回的值是一样的。

echo -n foo | md5sum
acbd18db4cc2f85cedef654fccc4a4d8  -
  1. 您可以在sqlplus或sql developer中直接调用或执行sql语句。我在这两个客户端中测试了针对11g的sql语句。
  2. 您可以使用任何能够向数据库发送语句的C、C#、Java或其他编程语言。需要能够理解sql语句的是调用端的数据库。在11g的情况下,代码将可行。
  3. @tbone提供了有关dbms_obfuscation_toolkit被弃用的重要警告。但这并不意味着您的代码在12c中无法使用。它仍然可以工作,但您最好最终切换到dbms_crypto包。在我的11g版本中,dbms_crypto不可用。

这个问题涉及到Oracle 11g,你说得对,这个问题没有针对11g进行回答。我也在寻找11g的解决方案。 这个解决方案对我有用,非常感谢。 - Mocking

1

为了在不将内容隐式重新编码为AL32UTF8的情况下,使用我所需的编码计算CLOB内容字段的MD5哈希值,我使用了以下代码:

create or replace function clob2blob(AClob CLOB) return BLOB is
  Result BLOB;
  o1 integer;
  o2 integer;
  c integer;
  w integer;
begin
  o1 := 1;
  o2 := 1;
  c := 0;
  w := 0;
  DBMS_LOB.CreateTemporary(Result, true);
  DBMS_LOB.ConvertToBlob(Result, AClob, length(AClob), o1, o2, 0, c, w);
  return(Result);
end clob2blob;
/

update my_table t set t.hash = (rawtohex(DBMS_CRYPTO.Hash(clob2blob(t.content),2)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接