Вопрос по security, php, zend-framework, string, compare – Безопасная функция сравнения строк

24

Я только что наткнулся на этот код в библиотеке HTTP Auth Zend Framework. Кажется, он использует специальную функцию сравнения строк, чтобы сделать ее более безопасной. Однако я не совсем понимаю комментарии. Кто-нибудь может объяснить, почему эта функция более безопасна, чем делать$a == $b?

<code>/**
 * Securely compare two strings for equality while avoided C level memcmp()
 * optimisations capable of leaking timing information useful to an attacker
 * attempting to iteratively guess the unknown string (e.g. password) being
 * compared against.
 *
 * @param string $a
 * @param string $b
 * @return bool
 */
protected function _secureStringCompare($a, $b)
{
    if (strlen($a) !== strlen($b)) {
        return false;
    }
    $result = 0;
    for ($i = 0; $i < strlen($a); $i++) {
        $result |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $result == 0;
}
</code>
Это то, чтоhash_equals делает в PHP 5.6+ caw

Ваш Ответ

1   ответ
36

Похоже, они пытаются предотвратитьвремя атаки.

In cryptography, a timing attack is a side channel attack in which the attacker attempts to compromise a cryptosystem by analyzing the time taken to execute cryptographic algorithms. Every logical operation in a computer takes time to execute, and the time can differ based on the input; with precise measurements of the time for each operation, an attacker can work backwards to the input.

Как правило, если для сравнения правильного пароля и неверного пароля требуется разное время, то вы можете использовать время для определения того, сколько символов пароля вы угадали.

Рассмотрим чрезвычайно некорректное сравнение строк (это в основном нормальная функция равенства строк с очевиднымwait добавлено):

function compare(a, b) {
    if(len(a) !== len(b)) { 
        return false;
    }
    for(i = 0; i < len(a); ++i) {
        if(a[i] !== b[i]) {
            return false;
        }
        wait(10); // wait 10 ms
    }
    return true;
}

Скажем, вы даете пароль, и он (последовательно) занимает некоторое время для одного пароля и примерно на 10 мс дольше для другого. Что это говорит вам? Это означает, что второй пароль содержит еще один правильный символ, чем первый.

Это позволяет вам взламывать фильмы - когда вы угадываете пароль по одному символу за раз (что гораздо проще, чем угадывать каждый возможный пароль).

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

Эта функция все еще имеет небольшую проблему:

if(strlen($a) !== strlen($b)) { 
    return false;
}

Это позволяет вам использовать атаки по времени для определения правильной длины пароля, что позволяет не пытаться угадать более короткие или более длинные пароли. В общем,Вы хотите хешировать свои пароли во-первых (который будет создавать строки равной длины), поэтому я предполагаю, что они не считают это проблемой.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededalwaysError: User Rate Limit Exceeded
Error: User Rate Limit ExceededstrlenError: User Rate Limit Exceeded

Похожие вопросы