web-dev-qa-db-ja.com

Oracleで行のsha1-hashを作成する

Oracleデータベースのselectで行の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はそれと関係があると思いますが、私はまだそれを頭で包むことができていません...

どんなポインタでも大歓迎です。

15
PrometheusDrake

パッケージ DBMS_CRYPTO は、ハッシュを生成するための正しいパッケージです。デフォルトではPUBLICに付与されていません。具体的に付与する必要があります(GRANT EXECUTE ON SYS.DBMS_CRYPTO TO user1)。

この関数の結果はデー​​タ型RAWです。 RAW列に格納するか、RAWTOHEXまたはVARCHAR2関数を使用してUTL_ENCODE.BASE64_ENCODEに変換できます。

HASH関数は、入力として3つのデータ型(RAWCLOB、およびBLOB)を受け入れるようにオーバーロードされています。 暗黙的な変換のルール のため、入力としてVARCHAR2を使用すると、OracleはそれをRAWに変換しようとしますが、この変換は機能するだけなので失敗する可能性があります16進文字列を使用します。

VARCHAR2を使用する場合は、入力をバイナリデータ型または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 のドキュメントに追加情報があります。

24
Vincent Malgrat

DBMS_cryptoパッケージはvarchar2をサポートしていません。これはraw型で機能するため、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;

この関数は、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;

楽しい!

3
Israel Rocha

誰かが検索するなら、ここに置くだけです。

Oracle 12では、standard_hash(<your_value>, <algorythm>)関数を使用できます。パラメータ_<algorythm>_が定義されていない場合、SHA-1ハッシュを生成します(出力データ型raw(20)

2
Sheyanoff