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

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

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

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

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... и т. д., пока время, затраченное службой, не увеличится, указывая на то, что у них совпадает первый символ. Затем второй символ может быть изменен, пока полная подпись не совпадет.

Другие вопросы по тегам