Хотите найти полезное решение для защиты паролей в приложении PHP / MySQL? - PullRequest
4 голосов
/ 30 декабря 2010

После прочтения о хешировании / посылке паролей в течение целого дня (не ври!) Мне нужно найти решение, которое работает, может быть использовано последовательно, и примерно для безопасности достаточно длямножество различных сайтов / приложений, использующих общую кодовую базу.

Итак, вот идея пользовательской таблицы MySQL:

users { id, username, password_hash, password_salt }

.. и псевдо-код:

$s_algo       = 'sha1';
$i_iterations = 1000;
$s_password   = 'mypw123xyuACE&.!3';
$s_salt       = hash($s_algo,uniqid(mt_rand(),true));
$s_result     = $s_password;
for ($i       = 0; $i < $i_iterations; $i++) {
    $s_result    = hash($s_algo,$s_result . $s_salt);
}

echo 'Password: ' . $s_password . "\n";
echo 'Algorithm: ' . $s_algo . "\n";
echo 'Iterations Completed: ' . $i . "\n";
echo 'Salt  : ' . $s_salt . "\n";
echo 'Result: ' . $s_result . "\n";
echo 'Length: (Salt:) ' . strlen($s_salt) . ' (Result:) ' . strlen($s_result) . "\n";

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

Из моего прочтения я подозреваю, что могут быть бесконечные споры о том, каким должен быть $ s_algo (хорошо, возможно,НЕ md5), а также $ i_iterations.Итак, давайте просто рассмотрим, что они переменные в этом проблемном сценарии, которые могут меняться в зависимости от конкретного контекста, то есть ограничений хранилища, проблем с нагрузкой на сервер и т. Д.

методология создания пользовательских паролей в PHP вообще звучит?Должен ли вообще быть цикл for?В порядке ли начальный код создания соли?Является ли избыточным количество соли по времени хранения (равным возможной длине хеша).Пожалуйста, люди, выбирайте дыры (но не слишком много!) ..

Другие мысли:
- А как насчет hash_hmac () - это критическое улучшение по сравнению с несколькими итерациями hash ()?
- PBKDF2

Ответы [ 2 ]

4 голосов
/ 30 декабря 2010

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

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

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

function randomChar($length) {
    $characters = array("A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "~", "!", "@", "#", "%", "^", "&", "(", ")", ":", "{", "[", "]", "}", "|", "<", ">", ".", ",", "/", "?", "_", "+", "-", "=");
    $charactersNumber = count($characters);
    $charactersNumber--;
    $randomLength = 0;
    while ($randomLength < $length) {
        $currentCharacter = $characters[rand(0,$charactersNumber)];
        if ($currentCharacter == $previousCharacter) {
            $currentCharacter = $characters[rand(0,$charactersNumber)];
        }
        $random .= $currentCharacter;
        $previousCharacter = $currentCharacter;
        $randomLength++;
    }
    return $random;
}

Ответ на итерационный вопрос: если x = хеш (пароль + соль) и с тех пор x = хеш (x + соль)

и 1 оценка x занимает 10 мс, то 2займет 20 и так далее.Итак ... 25 оценок = 250 мс и 1000 = 10 000 мс.

Хотя для каждого из них не потребуется 10 мс, даже 0,5 мс на 1000 все равно полсекунды.

Если вытолько принимаемые буквенно-цифровые пароли, и пароль был длиной 8 символов, каждая итерация добавляла бы на 62 ^ 8 (если они еще не нашли пароль) больше хэшей, потому что им пришлось бы делать другое, для каждой отдельной комбинации, которую они пробовали.*

1 голос
/ 30 декабря 2010

Я прочитал вчера статью в ответ на один из моих вопросов о безопасности здесь: http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html

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

Я прочитал в руководствах php это: http://www.php.net/manual/en/function.hash.php#89574, где парень провел тест каждого алгоритма и определил скорость каждого.И на основании моих показаний и того, что я использую RipeMD с солью в 50 символов.Что вы спрашивали: Дело в том, что вы генерируете случайную соль, а затем сохраняете ее в базе данных, которая кажется излишне избыточной.Лично я предпочел бы, чтобы в моем php-коде была спрятана одна соль, а не много уникальных солей, вложенных в базу данных.Плюс, почему ты хешишь соль?

...