16

我在 Oracle 数据库的选择中对一行进行 sha1-hash 时遇到问题。我在MSSQL中做了如下:

SELECT *,HASHBYTES('SHA1',CAST(ID as varchar(10)+
  TextEntry1+TextEntry2+CAST(Timestamp as varchar(10)) as Hash
FROM dbo.ExampleTable
WHERE ID = [foo]

但是,在使用 Oracle 时,我似乎找不到可以使用的类似功能。就我的谷歌搜索而言,我猜测 dbms_crypto.hash_sh1 与它有关,但我还没有能够将我的大脑包裹在它周围......

任何指针将不胜感激。

4

4 回答 4

27

DBMS_CRYPTO是生成哈希的正确包。默认情况下不授予 PUBLIC,您必须专门授予它 ( GRANT EXECUTE ON SYS.DBMS_CRYPTO TO user1)。

此函数的结果是 datatype RAW。您可以将其存储在RAW列中或VARCHAR2使用RAWTOHEXorUTL_ENCODE.BASE64_ENCODE函数将其转换为。

HASH函数被重载以接受三种数据类型作为输入RAWCLOBBLOB。由于隐式转换的规则,如果您使用 aVARCHAR2作为输入,Oracle 将尝试将其转换为RAW并且很可能会失败,因为此转换仅适用于十六进制字符串。

如果使用VARCHAR2then,则需要将输入转换为二进制数据类型或 a CLOB,例如:

DECLARE
   x RAW(20);
BEGIN
   SELECT sys.dbms_crypto.hash(utl_raw.cast_to_raw(col1||col2||to_char(col3)), 
                               sys.dbms_crypto.hash_sh1) 
     INTO x 
     FROM t;
END;

您将在文档中找到更多信息DBMS_CRYPTO.hash

于 2009-11-17T16:18:19.637 回答
9

DBMS_crypto 包不支持 varchar2。它适用于原始类型,因此如果您需要 varchar2,则必须对其进行转换。这是一个示例函数,展示了如何执行此操作:

declare
  p_string varchar2(2000) := 'Hello world !';
  lv_hash_value_md5    raw (100);
  lv_hash_value_sh1    raw (100);
  lv_varchar_key_md5   varchar2 (32);
  lv_varchar_key_sh1   varchar2 (40);
begin
  lv_hash_value_md5 :=
     dbms_crypto.hash (src   => utl_raw.cast_to_raw (p_string),
                       typ   => dbms_crypto.hash_md5);

  -- convert into varchar2
  select   lower (to_char (rawtohex (lv_hash_value_md5)))
    into   lv_varchar_key_md5
    from   dual;

  lv_hash_value_sh1 :=
     dbms_crypto.hash (src   => utl_raw.cast_to_raw (p_string),
                       typ   => dbms_crypto.hash_sh1);

  -- convert into varchar2
  select   lower (to_char (rawtohex (lv_hash_value_sh1)))
    into   lv_varchar_key_sh1
    from   dual;

  --
  dbms_output.put_line('String to encrypt : '||p_string);
  dbms_output.put_line('MD5 encryption : '||lv_varchar_key_md5);
  dbms_output.put_line('SHA1 encryption : '||lv_varchar_key_sh1);
end;
于 2012-02-28T09:36:10.080 回答
4

你可以在你喜欢的包中定义这个函数,我在 utils_pkg 中定义。

FUNCTION SHA1(STRING_TO_ENCRIPT VARCHAR2) RETURN VARCHAR2 AS 
BEGIN 
RETURN LOWER(TO_CHAR(RAWTOHEX(SYS.DBMS_CRYPTO.HASH(UTL_RAW.CAST_TO_RAW(STRING_TO_ENCRIPT), SYS.DBMS_CRYPTO.HASH_SH1))));
END SHA1;

现在调用它

SELECT UTILS_PKG.SHA1('My Text') AS SHA1 FROM DUAL;

回应是

SHA1
--------------------------------------------
5411d08baddc1ad09fa3329f9920814c33ea10c0

您可以从某个表中选择一列:

SELECT UTILS_PKG.SHA1(myTextColumn) FROM myTable;

享受!

于 2015-09-18T16:25:10.257 回答
4

只是放在这里,如果有人会搜索。

在 Oracle 12 中,您可以使用standard_hash(<your_value>, <algorythm>)函数。如果没有<algorythm>定义参数,它将生成 SHA-1 哈希(输出数据类型raw(20)

于 2018-06-08T07:36:53.003 回答