旧的 Python 哈希从左到右 - 为什么不好?

1 投票
5 回答
615 浏览
提问于 2025-04-16 12:35

我正在学习如何保护网站免受安全攻击。下面的链接有个不错的教程,但有一句话让我感到困惑:

http://google-gruyere.appspot.com/part3#3__client_state_manipulation中,在“Cookie 操作”部分,Gruyere提到Python的哈希函数不安全,因为它是从左到右进行哈希的。

Gruyere应用程序使用以下方式来加密数据:

# global cookie_secret; only use positive hash values
h_data = str(hash(cookie_secret + c_data) & 0x7FFFFFF)

c_data是用户名;cookie_secret是一个静态字符串(默认情况下就是空字符串'')

我明白在更安全的哈希函数中,任何一个小的变化都会产生完全不同的结果,但我不明白为什么这不安全,因为不同的c_data会生成完全不同的哈希值!

编辑:那要如何破解这样的哈希呢?

5 个回答

2

Python自带的哈希函数并不是为了安全或加密用途而设计的。它的主要目的是为了高效地把Python对象存储到字典里。

内部的哈希实现太过于可预测(碰撞太多),所以不适合用在安全方面。比如,下面的说法都是正确的:

hash('a') < hash('b')
hash('b') < hash('c')
hash('c') < hash('d')

这种顺序性使得它在字典存储方面表现得非常好,这正是它设计的初衷。

如果你想创建一个安全的哈希,应该使用hashlib库。

4

我觉得这个解释有点糟糕。Python的hash()函数不安全,是因为很容易出现碰撞,但“从左到右处理哈希”跟为什么容易出现碰撞没有关系。加密安全哈希也是按顺序处理数据的;它们通常一次处理128位或256位的数据,而不是每次处理一个字节,这只是实现上的一个细节。

需要说明的是,hash()不安全并不是Python的一个错误,因为它本来就不是为了这个目的。它是Python字典实现的一个公开细节,字典使用的是哈希表,而且你通常不希望你的哈希表使用安全的哈希函数,因为那样会让速度变得非常慢,失去哈希表的意义。Python在hashlib模块中提供了安全的哈希函数。

使用不安全的哈希并不是你展示的代码唯一的问题,但绝对是最重要的问题。

4

这个评论可能想表达的是,对于大多数哈希函数来说,如果你知道了 HASH(m) 的结果,那么计算 HASH(m . x) 是很简单的,其中 . 表示把两个东西拼接在一起。

所以,如果你是用户 ro,服务器给你发送了 HASH(secret . ro),那么你就可以很轻松地计算出 HASH(secret . root),这样你就可以以另一个用户的身份登录了。

撰写回答