2009-11-17 16 views
14

Ho riscontrato un problema con la creazione di una riga 1 in una selezione in un database Oracle. L'ho fatto in MSSQL come segue:Creazione di uno sha1-hash di una riga in Oracle

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

Tuttavia, non riesco a trovare una funzione simile da utilizzare quando si lavora con Oracle. Per quanto mi riguarda, credo che dbms_crypto.hash_sh1 abbia qualcosa a che fare con esso, ma non sono ancora riuscito a circondarmi ...

Qualsiasi suggerimento sarebbe molto apprezzato.

risposta

23

Il pacchetto DBMS_CRYPTO è il pacchetto corretto per generare gli hash. Non è concesso a PUBLIC per impostazione predefinita, sarà necessario concederlo in modo specifico (GRANT EXECUTE ON SYS.DBMS_CRYPTO TO user1).

Il risultato di questa funzione è del tipo di dati RAW. È possibile memorizzarlo in una colonna RAW o convertirlo in VARCHAR2 utilizzando le funzioni RAWTOHEX o UTL_ENCODE.BASE64_ENCODE.

La funzione HASH è sovraccarico di accettare tre tipi di dati come input: RAW, CLOB e BLOB. A causa dello rules of implicit conversion, se si utilizza uno VARCHAR2 come input, Oracle proverà a convertirlo in RAW e molto probabilmente non funzionerà poiché questa conversione funziona solo con stringhe esadecimali.

Se si utilizza VARCHAR2 allora, è necessario convertire l'input per un tipo di dati binario o un CLOB, per esempio:

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; 

troverete ulteriori informazioni nella documentazione di DBMS_CRYPTO.hash

+2

Grazie per l'aiuto. Ho dovuto usare il valore dbms_crypto.hash_sh1 sta per (il numero intero 3) invece della costante per farlo funzionare quando si esegue un normale SQL. SELECT sys.dbms_crypto.hash (utl_raw.cast_to_raw (col1), 3) FROM t; – PrometheusDrake

+2

Non penso che sia esattamente corretto per 11g R2. 'dbms_crypto.hash' sembra avere 3 versioni sovraccaricate per' raw', 'blob' e' clob'. Il valore 'varchar2' deve essere esplicitamente convertito in' raw' con 'utl_i18n.string_to_raw' o' utl_raw.cast_to_raw'. Oppure usa 'clobs' per i dati dei caratteri. – user272735

+0

Cosa succede se ci sono alcune colonne che non hanno il tipo di dati stringa? – ca9163d9

7

Il DBMS_crypto il pacchetto non supporta varchar2. Funziona con il tipo raw quindi se hai bisogno di un varchar2 devi convertirlo. Ecco una funzione di esempio che mostra come fare questo:

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; 
3

È possibile definire questa funzione nel pacchetto preferito, ho definito in 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; 

Ora chiamarlo

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

La risposta è

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

È possibile selezionare una colonna da qualche tavolo:

SELECT UTILS_PKG.SHA1(myTextColumn) FROM myTable; 

Enjoy!

Problemi correlati