Как могло сравнение HMAC когда-либо не быть постоянным по времени в Python?

#python-3.x #security #hmac #timing-attack

#python-3.x #Безопасность #hmac #временная атака

Вопрос:

В Python есть метод, специально предназначенный для сравнения HMAC, чтобы предотвратить временные атаки: https://docs.python.org/3.7/library/hmac.html#hmac.compare_digest

И я прочитал о временных атаках здесь: https://security.stackexchange.com/questions/74547/timing-attack-against-hmac-in-authenticated-encryption

Мой вопрос в том, как это могло когда-либо не быть постоянным по времени? Было бы необходимо вычислить фактический HMAC, чтобы сравнить его, и это не похоже на то, что вы могли бы вычислить дайджест по 1 символу за раз, верно? В конце концов, это было бы просто сравнение строк, которое на 2 порядка быстрее, чем фактическое вычисление HMAC в моих тестах. Итак, где именно здесь находится поверхность атаки? Может кто-нибудь, пожалуйста, привести пример того, где именно находится фактическая уязвимость, если я не использую hmac.compare_digest() ?

Комментарии:

1. Потому что тест на равенство Python == не дает никаких гарантий, что это постоянное время.

2. Итак, по сути, вы признаете, что это чисто техническая корректность, и на самом деле это не практическая проблема… Это в значительной степени то, что я думал, что это было.

3. Хм, нет, это не так. Я говорю вам, что использование == открывает вам возможности для атак Oracle по времени.

Ответ №1:

В конце концов, это было бы просто сравнение строк, которое на 2 порядка быстрее, чем фактическое вычисление HMAC в моих тестах.

Но это не постоянное время. То, что они выполняются быстро, не означает, что разница не поддается измерению. Для bytes значений Python сначала проверяет равную длину и равные первые байты, прежде чем использовать memcmp для тестирования остальных. Для строк Python сравнивает длину, затем вид (если строка использует 1, 2 или 4 байта на символ), затем также использует memcmp .

На странице руководства Linux для memcmp явно указано:

Не используйте memcmp() для сравнения критически важных данных безопасности, таких как криптографические секреты, потому что требуемое процессорное время зависит от количества равных байтов. Вместо этого требуется функция, которая выполняет сравнения с постоянным временем. Некоторые операционные системы предоставляют такую функцию (например, NetBSD consttime_memequal() ), но в POSIX такая функция не указана. В Linux может потребоваться реализовать такую функцию самостоятельно.)

Достаточно решительный злоумышленник может воспользоваться этой слабостью, чтобы выяснить, какой хэш вы сохранили, по сравнению с хэшем данных, которые он отправляет.

Временные атаки позволяют подделывать подписи. Скажем, служба хранит информацию авторизации в токене, совместно используемом с клиентом. Если бы клиент мог изменить этот токен, он мог бы получить доступ, которого в противном случае у него не было бы. Для защиты от этого токен подписывается с использованием подписи HMAC, позволяя серверу проверять возвращенный токен, прежде чем принимать его как действительный. Если данные авторизации не соответствуют подписи, токен отклоняется.

Если сервер выполняет это:

 auth_data, signature = split_token(token)
expected = hmac_signature(auth_data)
if signature == expected:
    # ...
  

тогда злоумышленник может определить, сколько символов поддельной подписи соответствует ожидаемой подписи, и соответствующим образом скорректировать. Они начинаются с XXXXX:000000... , затем пробуют XXXXX:1000000... и т.д., Пока время, затрачиваемое службой, не увеличится, указывая, что у них есть совпадающий первый символ. Затем второй символ может быть изменен, пока не совпадет полная подпись.

Комментарии:

1. Разве все это не совершенно бессмысленно, если у злоумышленника уже есть дайджест? Они могли бы просто сделать это на своем собственном компьютере.

2. @dvtan: нет, у злоумышленника нет дайджеста, он пытается выяснить, как создать новые хэши.

3. @dvtan: вы ссылались на статью, в которой именно это объясняется, что у злоумышленника нет дайджеста, и ему не нужен дайджест, он хочет знать, как сгенерировать новый дайджест для данных, которыми они управляют.

4. ах да, я думал об атаках методом грубой силы на секретный ключ… моя ошибка it_hurt_itself_in_confusion.jpeg

5. Я все еще думаю, что это слишком теоретично, и случайные отклонения полностью затмили бы любые временные различия на реальной практике