【问题标题】:Why do we need to add a "sleep" method to make a constant time attack succeed?为什么我们需要添加一个“sleep”的方法来让一个恒定时间攻击成功呢?
【发布时间】:2021-03-17 08:37:39
【问题描述】:

在这个网站:http://elijahcaine.me/remote-timing-attacks/,作者很好地描述了什么是恒定时间攻击以及如何防范这种类型的漏洞。

但是在作者做过的代码中:

# secret.py
from time import sleep # Used to exaggerate time difference.
from sys import argv   # Used to read user input.

def is_equal(a,b):
    """Custom `==` operator"""
    # Fail if the strings aren't the right length
    if len(a) != len(b):
        return False

    for i in range(len(a)):
        # Short-circuit if the strings don't match
        if a[i] != b[i]:
            return False

        sleep(0.15) # This exaggerates it just enough for our purposes

    return True

# Hard-coded secret globals FOR DEMONSTRATIONS ONLY
secret = 'l33t'

# This is python for "If someone uses you as a script, do this"
if __name__ == '__main__':

    try:
        # The user got it right!
        if is_equal(str(argv[1]), secret):
            print('You got the secret!')

        # The user got it wrong
        else:
            print('Try again!')

    # The user forgot to enter a guess.
    except IndexError:
        print('Usage: python secret.py yourguess\n' \
             +'The secret may consist of characters in [a-z0-9] '\
             +'and is {} characters long.'.format(len(secret)))

我不明白为什么我们必须添加这行才能使恒定时间攻击成功:

sleep(0.15) # This exaggerates it just enough for our purposes

在网站上,作者说:

它夸大了计算 is_equal 函数所需的时间。

我已经试过了,我们需要一个“睡眠”的方法来让这个攻击成功。为什么要夸大时间?

【问题讨论】:

    标签: python security constant-time


    【解决方案1】:

    编辑 1:

    为什么我们需要夸大时间?

    我们需要夸大时间来展示两个角色匹配时和不匹配时的时差。所以在这种情况下,如果 a 和 b 的第一个字符匹配,则方法休眠,然后如果第二个字符不匹配,则函数返回。这需要 1 个比较时间 + 睡眠(0.15)+ 1 个比较时间。 另一方面,如果第一个字符不匹配,则函数在 1 个比较时间内返回,因此攻击者可以看到它们是否匹配任何字符。该示例使用此睡眠来演示此时间差。

    为了避免这种情况发生,is_equal 函数应该以某种方式实现,该函数的响应时间是静态的。

    使用您提供的示例:

    def is_equal(a,b):
        _is_equal = True
    
        if len(a) != len(b):
            return False
    
        for i in range(len(a)):
            if a[i] != b[i]:
                _is_equal = False
    
        return _is_equal
    

    secrets 模块中有一个内置函数可以解决这个问题。 compare_digest()

    【讨论】:

    • @BoriszJuasz,你没有回答这个问题。问题不是关于使用什么来防止攻击,而是关于博客文章中演示攻击的细节。 “为什么要夸大时间?我试过了,我们需要一个‘sleep’的方法来让这次攻击成功。为什么?”
    • 感谢您的回复,我错过了这个问题。我编辑了我的答案。
    【解决方案2】:

    “匹配”循环有两种可能的路径:

    for i in range(len(a)):
        # Short-circuit if the strings don't match
        if a[i] != b[i]:
            return False
    
        sleep(0.15) # This exaggerates it just enough for our purposes
        return True
    
    1. if a[i] != b[i] 评估为 True - 不匹配,退出函数。
    2. if a[i] != b[i] 评估为 False - 匹配,在离开函数之前继续 Sleep(0.15)

    Sleep(0.15) 如果字符匹配会在这两个路径之间增加显着的时间差。这反过来允许在所有尝试中简单地使用max 来识别密钥的正确字符。没有这种夸张,您需要寻找匹配时间的统计显着差异。

    作者在这里提到了这一点:

    [对作者而言]最重要的是,我们不需要使用 StatisticsTM 找出秘密,多次评估每个输入,然后 收集/处理该计时数据,大约需要 1 个 评估匹配字母的时间比评估匹配的字母要长 评估一个不匹配的字母

    使用调试行查看有睡眠和没有睡眠的时间有何不同。

    # Uncomment the following line for fun debug output
    print('max {} min {}'.format(max(guess_times), min(guess_times)))
    
    # Add this line to see full guess_times list    
    print(['{:.2f}'.format(elem) for elem in guess_times])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 2015-09-12
      相关资源
      最近更新 更多