Как реализовать соль в моем логине для паролей?



Я хочу реализовать соль в моей системе входа в систему, но я немного запутался в том, как это должно работать. Я не могу понять логику этого. Я понимаю, что md5-это односторонний алгоритм, и все функции, с которыми я столкнулся, похоже, хешируют все вместе. Если это так, то как можно получить пароль обратно для сравнения? Мой самый большой вопрос: Как солить пароль пользователя безопаснее, чем просто хэшировать пароль? Если база данных не будет нарушена, хэш с солью находится в базе данных. Разве это не все, что нужно хакеру?



Я также нашел еще один пост здесь, где другой разработчик сказал:




" убедитесь, что ваша соль и алгоритм
сохранено отдельно на базе"




Я хотел бы хранить соль в базе данных. Это действительно проблема, если я это сделаю?



Я ищу некоторую помощь в понимании того, как это работает и что лучше практика может быть. Любая помощь очень ценится.





изменить:
Я хочу поблагодарить всех за ответы и идеи. Хотя сейчас я могу быть более смущен, это, безусловно, был опыт обучения для меня. Еще раз спасибо ребята.

718   8  

8 ответов:

хэш-функция всегда возвращает одно и то же значение для одной и той же входной строки. Допустим, мой пользователь (Алиса) имеет пароль secret. Хеширование secret используя md5() приводит к следующему хэшу

5ebe2294ecd0e0f08eab7690d2a6ee69

С помощью словаря (список общих слов и пароль) или один из различных сайтов, которые предлагают вам эту услугу, злоумышленник (Мэллори) может легко узнать пароль секрет, когда он видит в своем словаре, что 5ebe2294ecd0e0f08eab7690d2a6ee69 = secret.

в процесс засолки перед хэшированием затрудняет использование словарной атаки, не зная вашей соли. Рассмотрим следующее:

<?php
$salt = '@!#%$@#$@SADLkwod,sdaDwqksjaoidjwq@#@!';
$hash = md5($salt . 'secret');

полученный хэш теперь b58ad809eece17322de5024d79299f8a но пароль Алисы все еще secret. Теперь, если Мэллори доберется до соленого хэша, скорее всего, она не найдет ответа в своем словаре. Если она это сделает, словарь даст ей неправильный ответ.

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

если вы собираетесь использовать динамическую соль, вам нужно будет использовать базу данных. Используйте ненулевой столбец существующих допустимых данных для построения вашей соли (blowfish-зашифрованная строка имени пользователя на основе секретного ключа шифрования обычно криптографически защищена). Не используйте отдельную колонку для соли. Если вы не можете использовать существующий столбец, включите соль в тот же столбец, что и ваш хэш. Например, используйте первые 32 символа для вашей 128-битной соли, а затем последние 40 для вашего 160-битного хэша. Следующая функция будет генерировать такой хэш:

function seeded_sha1($string, $seed_bits) {
    if(($seed_bits % 8) != 0) {
        throw new Exception('bits must be divisible by 8');
    }

    $salt = '';
    for($i = 0; $i < $seed_bits; $i+=8) {
        $salt .= pack('c', mt_rand());
    }

    $hexsalt = unpack('h*hex', $salt);

    return $hexsalt['hex'] . sha1($salt . $string);
}

function compare_seeded_sha1($plain, $hash) {
    $sha1 = substr($hash, -40);
    $salt = pack('h*', substr($hash, 0, -40));

    $plain_hash = sha1($salt . $plain);
    return ($plain_hash == $sha1);
}

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

Примечание: там возможны ли другие типы атаки на md5() именно поэтому вы используете более безопасный алгоритм хэширования,sha1() например. Или, еще лучше, использовать Portable PHP password hashing framework, который был разработан с учетом безопасности и обратно совместим практически с любой версией PHP.

require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );

// $hash would be the $hashed stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

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

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

хранить соли отдельно не необходим для того чтобы приобрести это преимущество. Теоретически это было бы еще более безопасно, потому что это нейтрализовало бы слабость словаря или коротких паролей. На практике это не стоит беспокоиться, потому что в конце дня вам нужен доступ к солям где-то для проверки паролей. Кроме того, попытка разделить их приведет к более сложным системам - и чем сложнее система, тем больше возможностей для дыр в безопасности.

Edit: мои рекомендации:

  • генерации псевдослучайных соль для каждого пользователя и хранить в БД
  • используйте хэш на основе bcrypt
  • в идеале, не реализуйте его самостоятельно, используйте существующий библиотека вместо

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

для хорошего объяснения см.:http://codahale.com/how-to-safely-store-a-password/

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

вы можете использовать одну и ту же соль для каждого пользователя вместе с хорошей идеей Юрая объединить пароль с другими неизменяемыми полями базы данных (уникальными для пользователя). Но следить за эта информация привязывается к паролю. Если вы должны были хэшировать имя пользователя + пароль вместе, чтобы гарантировать уникальный хэш, вы не сможете изменить имя пользователя, не создав нового пользователя и не требуя от них установить новый пароль.

в качестве примера наличия уникальной соли для каждого пользователя и хранения ее вместе с хэшем пароля, я укажу / etc / shadow в вашей типичной системе Linux.

root@linux:/root# cat /etc/shadow | grep root
root:$oL5TTZxL$RhfGUZSbFwQN6jnX5D.Ck/:12139:0:99999:7:::

здесь oL5TTZxL соль и RhfGUZSbFwQN6jnX5D.Ck/ - это хэш. Простой текстовый пароль -root в этом случае и алгоритм хэша, который использует моя система,-это алгоритм пароля BSD на основе MD5. (более новые системы, чем мои, имеют лучшие алгоритмы хэширования)

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

как вы упомянули, алгоритмы хэширования работают только в одну сторону (или только если они достаточно сильны: - D)

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

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

например, допустим, у вас есть users таблица с этими столбцами:

id
username
password
created_at

колонки id и created_at после того, как заполнены никогда не должны быть изменены..

Итак, когда вы хеширования пароля пользователя вы можете сделать так:

<?php
    $staticSalt = '!241@kadl;ap][';
    $userPass = 'my new pass';
    // assuming $user variable is already populated with DB data
    // we will generate new hash from columns and static salt:
    $genPass = sha1($user['id'] . $userPass . $user['created_at'] . $staticSalt);
?>

Я надеюсь, что это один помогает:) ура

хэширование паролей предназначено для сохранения этих паролей в секрете от ваших собственных администраторов.

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

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

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

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

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

некоторые другие Примечания:

a) вы можете использовать bcrypt на комбинации пароля/соли, чтобы замедлить атаку грубой силы злоумышленника. Но поскольку мы предполагаем администраторов, они могут быть терпеливы.

b) держать соль отдельно от хэш пароля не является эффективной защитой, мы предполагаем, что администраторы в конце концов.

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

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

например, если хакер получает доступ к вашей базе данных, и пароли не засолены, то он может искать хэши в своей базе данных хэшей (см. http://en.wikipedia.org/wiki/Rainbow_table), чтобы получить исходные пароли.

Comments

    Ничего не найдено.