Как я реализую соль в свой вход в систему для паролей?

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

Я также нашел другое сообщение здесь на ПОЭТОМУ, где другой разработчик сказал:

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

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

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


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

55
задан JabberwockyDecompiler 8 May 2015 в 10:04
поделиться

8 ответов

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

5ebe2294ecd0e0f08eab7690d2a6ee69

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

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

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

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

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

Если вы собираетесь использовать динамическую соль, вам нужно будет использовать базу данных. Используйте ненулевой столбец существующих действительных данных, чтобы построить свою соль (зашифрованная с помощью 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-фреймворк для хеширования паролей , который был разработан с учетом требований безопасности и обратно совместим практически с любой версией 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';
}
19
ответ дан 7 November 2019 в 07:25
поделиться

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

5
ответ дан 7 November 2019 в 07:25
поделиться

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

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

1
ответ дан 7 November 2019 в 07:25
поделиться

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

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

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

Изменить: Мои конкретные рекомендации:

  • Сгенерировать длинную псевдослучайную соль для каждого пользователя и сохранить в БД
  • В идеале использовать хэш на основе bcrypt
  • , не реализовывать его самостоятельно, используйте существующая библиотека вместо
31
ответ дан 7 November 2019 в 07:25
поделиться

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

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

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

Например, предположим, что у вас есть пользователей Таблица со следующими столбцами:

id
username
password
created_at

columns 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);
?>

Надеюсь, это поможет :) Ура

2
ответ дан 7 November 2019 в 07:25
поделиться

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

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

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

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

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

7
ответ дан 7 November 2019 в 07:25
поделиться

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

Хорошее объяснение см .: http://codahale.com/how-to-safely-store-a- пароль /

15
ответ дан 7 November 2019 в 07:25
поделиться

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

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

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

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

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

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

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

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

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

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

2
ответ дан 7 November 2019 в 07:25
поделиться
Другие вопросы по тегам:

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