繁体   English   中英

pbkdf2和哈希比较

[英]pbkdf2 and hash comparison

我使用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]

此函数返回二进制摘要,然后将其摘要编码为base64并保存到数据库中。 当用户登录时,该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字符串,然后比较两个二进制散列,但是如果用户有一个cookie与base64字符串,我直接将其与来自数据库。

第二个问题是关于盐的:

os.urandom返回二进制字符串,但是在将其用于哈希生成之前,我也将其编码为base64。 有什么原因为什么我不应该这样做并以二进制形式使用salt?

要回答问题1 :比较字节和比较base64编码的字符串时,没有什么主要的安全区别...您只是比较nn*4/3元素。 使用base64时,运行时间将增加4/3 ,但是时间仍然不多:)

就是说,关于类似的“恒定时间”比较功能,有一个python开发人员讨论 ,并且他们碰到了一些VM级别的陷阱-如果您的输入是unicode字符串而不是bytes ,并且尤其是unicode包含非ASCII字符,可能仍然存在一些细微的定时攻击(比短路平等攻击小几个数量级)。 因此,如果可能,我会坚持使用字节(无论是二进制数据还是ASCII编码的base64数据)。 但是,对于PBKDF2,我不会担心,因为设计比较功能来克服定时攻击的方式更多地适用于HMAC签名,而不是密码哈希验证……但要安全起见总比对不起。

回答问题2 :对于不安全的构造(例如md5(salt+password) ,首先对salt进行编码将使攻击者可以使用现有的ASCII md5表来攻击整个摘要,而原始的二进制salt将使此类表无用。 但是,PBKDF2-HMAC进行了足够的处理,因此唯一重要的是,盐包含n位熵-无论是n/8原始字节还是n/6 base64字符,都不会影响安全性。

其他说明 :我只想补充一些与您发布的内容有关的要点...

  1. 为了安全起见,强烈建议使用SHA256 / 512代替SHA1作为PBKDF2-HMAC哈希函数,并且为了安全起见>> 10,000回合(自2012年起)。

  2. 将摘要发送到Cookie(甚至不加盐)中的想法令我感到潜在的不安全感……如果有人窃取了该Cookie(例如,跨站点脚本攻击),则他们有可能以用户身份登录(尽管我不知道其余的应用程序的安全设置)。 使用具有随机生成的会话ID的会话层(例如Beaker )可能是一个不错的选择。

  3. 我建议使用Passlib PBKDF2consteq实现,它的PBKDF2例程比光彦的例程快约5倍,并且可以利用M2Crypto(如果存在)。 (免责声明:我是Passlib的作者) 它也有一个现成的pbkdf2-sha256密码哈希函数,但是如果您要在cookie中发送摘要,那将用不了多少。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM