【问题标题】:hashes in python and oracle sql not matchingpython和oracle sql中的哈希不匹配
【发布时间】:2018-11-30 22:16:27
【问题描述】:

我必须使用函数来生成随机元素的哈希 (sha512)。第一个是oracle sql查询:

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

返回

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

当我尝试在 python 中为C1BEC41854 生成哈希时,我使用以下脚本

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

返回

a63f4d25b5f0fc51fb27ae1e1c5f4ff19edc7b790d2373071ae8f454e63766a19b69a200690a32a65dd57be5b47fec29ee15c354f52ad5916127bb4cf674ab37

你能帮我弄清楚为什么两个哈希值不相同吗?

【问题讨论】:

  • 该字符串 C1BEC41854 需要在被散列之前转换为字节(这不是魔术)。两种方法都使用相同的编码算法吗?也许一个具有默认的 UTF-8 编码,而另一个使用 ISO-8859-1 或其他。
  • 两种方法是否使用相同的填充?
  • 您是否使用任何盐来散列? (你应该)两边的盐相同吗?
  • @TheImpaler 不,我没有使用任何盐。 atmI 只是想生成一个匹配的哈希值。一旦这个工作,我将包括盐。 DBMS_CRYPTO.RANDOMBYTES() 也返回 RAW 所以这应该是字节,在 bytes.fromhex(h) 我在 python 中得到一个字节对象
  • 当我在没有 DBMS_CRYPTO.RANDOMBYTES() 的情况下尝试这个但使用定义的字符串 hallo 像这样:select RAND, dbms_crypto.hash(RAND, 6 /*SHA512*/) as sha512 from (select UTL_I18N.STRING_TO_RAW( 'hallo', 'AL32UTF8' ) as RAND from dual); 它工作得很好

标签: python sql oracle sha hashlib


【解决方案1】:

在您的 Oracle 查询中,您正在生成多个随机字节字符串。

试试这个来演示:

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

请注意 RAND 的三个不同值。因此,您生成的哈希实际上是针对与您想象的不同的字节序列。

要修复它,您可以使用 AskTom 提供的这个技巧

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

在子查询中包含 rownum 使 RAND 在您每次将其用作顶级 SELECT 中的字段时保持一致。

AskTom Question on the subject

【讨论】:

  • 出色的观察!
【解决方案2】:

这会给你同样的结果(大写):

SELECT sys.dbms_crypto.hash(
  hextoraw('C1BEC41854'),
  6--HASH_SH512
) from dual;

看起来你的字符串已经是一个十六进制值,所以我只是做了一个 hextoraw。如果它是像“Hello”这样的基本字符串,那么我会使用utl_raw.cast_to_raw

输出:

A63F4D25B5F0FC51FB27AE1E1C5F4FF19EDC7B790D2373071AE8F454E63766A19B69A200690A32A65DD57BE5B47FEC29EE15C354F52AD5916127BB4CF674AB37

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-27
    • 2021-04-23
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多