在Python中生成唯一哈希的最安全方法

问题描述 投票:0回答:3

我需要生成可在文件名中使用的唯一标识符,并且可以在给定相同输入值的情况下重现。我需要生成数百万个这样的标识符,因为源输入有数百万种组合。

为了简单起见,我将在示例中使用一个小集合,但实际集合可能相当大(数百个,也许数千个项目);大于可以手动编码到文件名中的值。

我注意到生成 UUID 的第 5 种方法允许您提供字符串输入。

> input_set = {'apple', 'banana', 'orange'}
> uuid.uuid5(uuid.NAMESPACE_URL, pickle.dumps(input_set)).hex
'f39926529ad45997984643816c1bc403'

文档说它在底层使用了

SHA1
。碰撞的风险是否太高?有没有更好的方法来可靠地散列唯一标识符?

python uuid
3个回答
8
投票

字符串发生 SHA1 冲突的可能性非常低。目前 SHA1 的已知冲突少于 63 个。

首次发现 SHA1 冲突

首次计算 SHA-1 哈希冲突。所需要的只是五个聪明的大脑......和 6,610 年的处理器时间

SHA1 在密码学领域不再被认为是安全的,但肯定超出了您的期望。

加密哈希函数被设计为单向函数。这意味着函数的逆函数“很难”计算。 (即知道输出绝不能帮助您确定输入)正如 Blender 在评论中指出的那样,这与碰撞的可能性无关。

查看生日悖论,了解有关如何计算碰撞概率的一些基本信息。

这个问题解决了 SHA1 冲突的可能情况。这篇文章指出

如果发现冲突可以证明可以从问题 P 中进行多项式时间还原,而问题 P 应该在多项式时间内无法解决,那么加密哈希函数就具有可证明的针对冲突攻击的安全性。然后该函数被称为可证明安全的,或者只是可证明的。

这里是“安全”哈希算法的列表。

更新 您在评论中指出您的输入远大于 SHA1 的 160 位限制。在这种情况下,我建议您使用 SHA3,因为输入的大小没有限制。查看 Python 文档以获取更多信息。

这是一个基本示例:

import sha3
k = sha3.keccak_512()
k.update(b"data")
k.hexdigest()
'1065aceeded3a5e4412e2187e919bffeadf815f5bd73d37fe00d384fe29f55f08462fdabe1007b993ce5b8119630e7db93101d9425d6e352e22ffe3dcb56b825'

8
投票

除了使用

pysha3
(参见 DoesData 的答案),您还可以使用内置模块
hashlib
:

import hashlib

h = hashlib.sha3_512() # Python 3.6+
h.update(b"Hello World")
h.hexdigest()

输出:

'3d58a719c6866b0214f96b0a67b37e51a91e233ce0be126a08f35fdf4c043c6126f40139bfbc338d44eb2a03de9f7bb8eff0ac260b3629811e389a5fbee8a894'

0
投票

如果

base64.urlsafe_b64encode
输出越小越好:

> import base64, hashlib

> base64.urlsafe_b64encode(hashlib.sha3_512('asdf'.encode()).digest())
b'jYjPWyD1Os164UebWzbcICF1OwSZAsdyR7snsTGzAL08qL7vKHVtzie4mQhnxFd6JTXn47dRQTmcoalMyEsOuQ=='

上面的输出长度为 88,而相应的十六进制长度为 128。

© www.soinside.com 2019 - 2024. All rights reserved.