Search code examples
pythonsqloracle-databaseshahashlib

hashes in python and oracle sql not matching


I have to functions to generate a hash (sha512) of a random element. The first one is a oracle sql query:

select RAND, DBMS_CRYPTO.HASH(RAND, 6 /*SHA512*/) as sha512 from 
    (select DBMS_CRYPTO.RANDOMBYTES(5) as RAND from DUAL);

which returns

RAND
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SHA512                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C1BEC41854                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
E4BD639D4726D294CB63B6DDC651C6B6F5708ED3FC9B2E08A71DD7D36958B7B13BD31ECA28039565121F3067167D719292A86B6CAD052EFC9A56923594946084

When I try to generate the hash for C1BEC41854 in python I use the following script

from hashlib import sha512
h = 'C1BEC41854'
b = bytes.fromhex(h)
print(sha512(b).hexdigest())

which returns

a63f4d25b5f0fc51fb27ae1e1c5f4ff19edc7b790d2373071ae8f454e63766a19b69a200690a32a65dd57be5b47fec29ee15c354f52ad5916127bb4cf674ab37

Can you please help me figure out why the both hashes are not identical?


Solution

  • In your Oracle query, you're generating multiple random byte strings.

    Try this to demonstrate:

    select RAND, RAND, RAND, DBMS_CRYPTO.HASH(RAND, 6 /*SHA512*/) as sha512 from 
        (select DBMS_CRYPTO.RANDOMBYTES(5) as RAND from DUAL);
    

    Note the three different values for RAND. So the hash you are generating is actually for a different byte sequence than you think it is.

    To fix it, you can use this bit of trickery courtesy of AskTom

    select RAND,DBMS_CRYPTO.HASH(RAND, 6 /*SHA512*/) as sha512 from 
        (select rownum, DBMS_CRYPTO.RANDOMBYTES(5) as RAND from DUAL);
    

    including rownum in the subquery makes RAND consistent each time you use it as a field in the top level SELECT.

    AskTom Question on the subject