我正在努力学习如何抵御网站上的安全攻击。下面的链接显示了一个很好的教程,但我对一个声明感到困惑:
在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会生成完整的不同哈希值!
编辑:如何打败像这样的哈希?
答案 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”的哈希是什么?)。