老蟒蛇哈希从左到右完成 - 为什么它不好?

时间:2011-02-26 18:45:33

标签: python string cookies encryption hash

我正在努力学习如何抵御网站上的安全攻击。下面的链接显示了一个很好的教程,但我对一个声明感到困惑:

http://google-gruyere.appspot.com/part3#3__client_state_manipulation中,在“Cookie操作”下,Gruyere说Pythons hash是不安全的,因为它从左到右散列。

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 个答案:

答案 0 :(得分:4)

我认为这只是一个不好的解释。 Python的hash()是不安全的,因为它很容易找到碰撞,但是“从左到右的哈希”与为什么无关,很容易找到碰撞。 Cryptographically secure hashes也严格按顺序处理数据;它们可能一次运行128或256位数据,而不是一次运行一个字节,但这只是实现的细节。

(应该说hash()不安全是而不是 Python中的一个错误,因为这不是它的用途。它是Python字典实现的公开细节{{ 3}},你通常想要你的哈希表的安全哈希函数,因为这会减慢它以至于它会破坏目的.Python确实提供了安全哈希函数hash tables模块。)

(使用不安全的哈希不是您展示的代码的唯一问题,但它是迄今为止最重要的问题。)

答案 1 :(得分:4)

评论可能试图得到的是,对于大多数哈希函数,如果给予HASH(m),那么对于任何HASH(m . x)(其中{{} x,很容易计算. {1}}是连接)。

因此,如果您是用户ro,并且服务器向您发送了HASH(secret . ro),那么您可以轻松计算HASH(secret . root),并以其他用户身份登录。

答案 2 :(得分:2)

Python的默认散列算法(对于所有类型,但它对字符串具有最严重的后果,因为它们通常用于安全性)是为了快速运行并且与dicts的实现一起玩得很好。它不是加密散列函数,您不应该将其用于安全性。请使用hashlib

答案 3 :(得分:1)

内置hash function的python不适用于安全的加密哈希。它的目的是便于有效地将Python对象存储到字典中。

internal hash implementations对于安全使用来说太可预测(太多碰撞)。例如,以下断言都是正确的:

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

这种顺序特性使得字典存储行为成为可能。

要创建安全哈希,请改用hashlib库。

答案 4 :(得分:0)

通过将数据附加到被散列的字符串的末尾并预测散列函数输出,可以“殴打”这样的散列。让我来说明一下:

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> data = 'root|admin|author'
>>> str(hash('' + data) & 0x7FFFFFF);
'116042699'
>>> data = 'root|admin|authos'
>>> str(hash('' + data) & 0x7FFFFFF);
'116042698'
>>> 

空字符串('')是您提到的空字符串的cookie秘密。在这个特定的例子中,尽管不是真正可利用的,但是可以看到哈希改变了1并且data last 字节也改变了“1”。现在,这个例子实际上并不是一个漏洞利用(省略了创建anything_here|admin格式的用户名使该用户成为管理员的事实),因为在用户名之后有一些数据(从左到右),所以即使你创建了一个用户名,非常接近被攻击的那个,然后字符串的其余部分以完全不希望的方式改变哈希。但是,如果cookie的格式为105770185|user07而不是105770185|user07||author,那么您可以轻松创建用户“user08”或“user06”,并且 compute 预测哈希值( hometask:“user08”的哈希是什么?)。