В PHP 5.6 введена hash_equals()
функция для безопасного сравнения хэшей паролей и предотвращения атак таймингов. Его подпись:
bool hash_equals(string $known_string, string $user_string)
Как описано в документации, $known_string
и $user_string
должны иметь одинаковую длину, чтобы функция эффективно предотвращала временные атаки (в противном случае false
возвращается немедленно, утечка длины известной строки).
Кроме того, в документах говорится:
Важно предоставить строку, предоставленную пользователем, как второй параметр, а не первый.
Мне кажется неинтересным, что функция не является симметричной по своим аргументам.
Вопрос:
- Почему важно, чтобы строка пользователя была указана последним?
Здесь выдержка из исходного кода функции:
PHP_FUNCTION(hash_equals)
{
/* ... */
if (Z_STRLEN_P(known_zval) != Z_STRLEN_P(user_zval)) {
RETURN_FALSE;
}
/* ... */
/* This is security sensitive code. Do not optimize this for speed. */
for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
result |= known_str[j] ^ user_str[j];
}
RETURN_BOOL(0 == result);
}
Для меня реализация полностью симметрична относительно двух аргументов. Единственная операция, которая может иметь какое-либо значение, - это оператор XOR.
-
Возможно ли, что оператор XOR выполняется в непостоянное время, в зависимости от значений аргументов? Может ли его время выполнения зависеть от порядка аргументов (например, если первый аргумент равен нулю)?
-
Или это примечание от PHP документирует "резервирование" для изменений в реализации в будущих версиях?
Изменить
Как сказано в Morpfh, первоначальная реализация была другой:
PHP_FUNCTION(hash_compare)
{
/* ... */
/**
* If known_string has a length of 0 we set the length to 1,
* this will cause us to compare all bytes of userString with the null byte which fails
*/
mod_len = MAX(known_len, 1);
/* This is security sensitive code. Do not optimize this for speed. */
result = known_len - user_len;
for (j = 0; j < user_len; j++) {
result |= known_str[j % mod_len] ^ user_str[j];
}
RETURN_BOOL(0 == result);
}
Как вы видите, проект реализации попытался обработать хэши разной длины, и он обработал аргументы асимметрично. Возможно, этот проект не является первым.
Подведение итогов: примечание в документе о порядках аргументов кажется остающимся от реализации проекта.