В конце концов, это будет простое сравнение строк, которое на 2 порядка быстрее, чем фактическое вычисление HMAC в моих тестах.
Но это не постоянное время . То, что они сделаны быстро, не означает, что разница не измерима. Для значений bytes
Python сначала проверяет одинаковую длину и равные первые байты, прежде чем использовать memcmp
для проверки остальных. Для строк Python сравнивает длину, затем kind (если строка использует 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...
и т. Д., Пока время, затраченное службой, не увеличится, указывая на то, что у них совпадает первый символ. Затем второй символ может быть изменен, пока полная подпись не совпадет.