我使用mitsuhiko的pbkdf2实现进行密码哈希:
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
return map(ord, h.digest())
buf = []
for block in xrange(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block))
for i in xrange(iterations - 1):
u = _pseudorandom(''.join(map(chr, u)))
rv = starmap(xor, izip(rv, u))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
此函数返回二进制摘要,然后将其编码在bas64中并保存到数据库中。此外,当用户登录时,Base64字符串被设置为cookie。
此函数用于密码哈希比较:
def comparePasswords(password1, password2):
if len(password1) != len(password2):
return False
diff = 0
for x, y in izip(password1, password2):
diff |= ord(x) ^ ord(y)
return diff == 0
我想知道在安全性方面,二进制哈希和Base64字符串的比较是否有任何不同?例如,当用户登录时,我会计算提交密码的二进制摘要,从数据库中解码Base64字符串,然后比较两个二进制哈希,但是如果用户有一个带有Base64字符串的cookie,我会直接将其与数据库中的a字符串进行比较。
第二个问题是关于盐:
操作系统。Uradom返回二进制字符串,但在用于哈希生成之前,我还将其编码为base64。有什么理由我不应该这样做并使用二进制形式的盐吗?
回答问题1:比较字节和比较base64编码字符串时,没有重大的安全性差异。。。您只是在比较n
或n*4/3
元素。使用base64时,运行时间将4/3
更长,但时间量仍然很小:)
也就是说,有一个关于类似的“恒定时间”比较函数的Python开发人员讨论,他们偶然发现了一些虚拟机级的问题——如果你的输入是Unicode
字符串而不是字节
,尤其是如果Unicode包含非ASCII字符,仍然可能存在一些微妙的定时攻击(数量级小于短路相等攻击)。因此,如果可能的话,我会坚持字节(无论是二进制数据还是ASCII编码的基64数据)。然而,在PBKDF2的情况下,我不会太担心,因为比较函数旨在击败的定时攻击更适用于HMAC签名,而不是密码哈希验证...
回答问题2:对于不安全的结构,如md5(盐密码)
,首先编码盐将允许攻击者使用现有的ASCII md5表攻击整个摘要,其中原始二进制盐将使这些表无用。然而,PBKDF2-HMAC做了足够多的破坏,唯一重要的是盐包含n个熵位——不管是以n/8
原始字节的形式,还是n/6
基64字符的形式,都不会影响安全。
其他注意事项:我只是想补充几点关于你发布的内容。。。
>
出于安全目的,我强烈建议使用SHA256/512而不是SHA1作为PBKDF2-HMAC哈希函数,以及
把摘要放在饼干里(即使是盐)的想法让我觉得潜在的不安全...如果有人偷了饼干(例如:反射形的XSS攻击),他们可能会以用户身份登录(尽管我不知道应用程序的其余安全设置)。使用具有随机生成的会话ID的会话层(例如:烧杯)可能是一个不错的选择。
我建议使用Passlib PBKDF2和consteq实现,它的PBKDF2例程大约比mitsuhiko快5倍,如果存在M2Crypto,可以利用它。(免责声明:我是Passlib的作者)。它还有一个现成的pbkdf2-sha256密码散列函数,不过如果您在cookie中发送摘要,它就没有那么多用处了。
我是相对较新的PHP,刚刚开始掌握盐的点,当谈到散列密码(我想?)。不管怎样,这是我的问题... 现在我有一个mysql数据库,用户名,密码,盐字段。密码字段长度为64个字符,盐字段为3个字符。在注册时,每个用户名被分配一个随机的盐。我对此没有任何问题(我相信)。首先,通过以下方式散列用户所需的密码: 然后,通过以下过程将用户所需的密码与pbkdf2中包含的盐进行散列,并将其输入数据库: 我的问题
求求你帮帮我!我正在尝试使用pbkdf2-sha256算法哈希密码。Password=“user1”,salt=“ifo7kxyswe7fiu3bovnowg=”,hashIterations=“27500”。我知道结果。必须类似于“ZnxO94AYITK7T+OJ1PXPZTVEQ+G82LFWT6VNSTBHZPEUWZGMPRJJVKAUEXGH1IQPZWMX1SRVTUMLN/JCM8G
我正在写一个Django应用程序,需要与现有的Java播放框架应用程序一起工作。Play应用程序使用PasswordHash.java来存储密码。它以冒号分隔的格式存储密码。每个哈希都存储为::。 例如,下面是密码“测试”的条目: 在这里,我们可以通过拆分字符串并找到: 迭代次数: 盐: PBKDF2哈希:。 我修改了Django的check_密码机制以与此格式兼容,但发现它认为密码不正确。我用了
我正在尝试使用Sinatra和BCrypt实现一种看似非常简单的身份验证方法,但显然我遗漏了一些东西... 用户会预先分配一个临时密码,该密码以明文形式存储在DB中。 我根据临时口令进行身份验证,然后创建salt和password_hash,并将它们作为字符串写入db(本例中为mongo)。 为了进行身份验证,我从db和用户口令中获取salt进行比较。 bcrypt::Engine.hash_se
我一直在研究散列/加密密码并将其存储在数据库中的正确方法。我知道盐和散列,所以我环顾四周,PBKDF2似乎是一个不错的选择。所以我找到了这个网站,它提供了一个很好的教程,以及一个适用于PHP的PBKDF2(这是我在我的网站上使用的)。 因此,我设置了我的网站,以使用这些功能生成/创建密码,但正如您在以下代码中看到的: salt在create_散列函数中生成,并存储在生成的散列中,该散列最终看起来像
问题内容: 我必须对指纹文件进行匹配才能匹配双峰。在2013年,对Java有何建议?我是否还应该比较文件大小,或者这是不必要的检查? 误报的可能性应该非常接近0 编辑:很多答案,谢谢。如今备份软件的标准是什么?SHA-256?更高?我猜md5不合适吗? 问题答案: 如果假阳性的概率必须 为零 ,而不是“比闪电击中的概率低”,则完全不能使用哈希算法;您必须逐字节比较文件。 值得一提的是,如果您可以使