safe_string_cmp 的目的是什么?

what is the purpose of safe_string_cmp?

Flask 新手,正在学习描述如何制作 REST 的课程API。

课程作者建议在身份验证章节中使用 werkzeug.security 中的 safe_str_cmp

如果有人能帮助理解该函数的用途以及 when/why 应该使用它,我将不胜感激。

测试字符串相等性的明显算法是这样的:

def strings_equal(s1, s2):
    if len(s1) != len(s2):
        return False
    for i in range(len(s1)):
        if s1[i] != s2[i]:
            return False
    return True

但是,使用此算法比较密码哈希值存在一个微妙的问题。当两个字符串在开头附近有不同的字符时,循环内部的 return 使算法更快,而当它们在开头附近有相同的字符时更慢。

这使得比较容易受到 timing attack;通过尝试使用已知散列值的密码并测量密码被拒绝所需的平均时间,攻击者可以统计确定两个散列值的开头有多少相同字符。通过尝试一系列不同的哈希值来连续发现一个或两个字节的真实密码哈希值,攻击者可以推断出其中的很大一部分,然后尝试在本地破解它。

安全字符串比较算法可能如下所示:

# warning: example only! this hasn't been proven secure!
# don't use in real code!

def strings_equal(s1, s2):
    if len(s1) != len(s2):
        return False
    result = True
    for i in range(len(s1)):
        # use & for non-short-circuiting
        result = result & (s1[i] == s2[i])
    return result

由于使用相同散列算法的所有密码散列应具有相同的长度,理想情况下,此比较应该始终花费相同的时间来比较两个散列,以防止计时攻击。 更一般地说,您应该在任何时候将用户输入与任何秘密字符串进行比较时使用安全字符串比较函数。