代码之家  ›  专栏  ›  技术社区  ›  Rotkiv

安全字符串的目的是什么?

  •  0
  • Rotkiv  · 技术社区  · 6 年前

    刚接触Flask,正在学习一门课程,介绍如何制作REST API。

    课程作者建议使用 safe_str_cmp 来自认证章节中的werkzeug.security。

    如果有人能帮助我理解这个函数的目的是什么,以及什么时候/为什么应该使用它,我将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  1
  •   kaya3 Amit Bera    6 年前

    测试字符串相等性的明显算法如下:

    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
    

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

    推荐文章