Почему PHP crypt() добавляет соль в хэш?

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

Пример:

$salt = "kr";
echo crypt("mysecret",$salt); //returns "kreOI.F7eOQMY"

Моя первая мысль была, не поможет ли это тому, кто пытается изменить ваш хэш?

Я посмотрел salt на википедию, в которой говорилось:

Для лучшей безопасности значение соли сохраняется в секрете.

Итак, я не понимаю, почему тогда функция crypt вернет все хэши, добавленные с использованием значения соли?

Есть ли причина для этого? Должно ли это быть проблемой безопасности?

Ответ 1

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

crypted password: xxabcdefghijklmn
                  ^^- salt
                    ^^^^^^^^^^^^^^-- crypted pw

if ('xx' + crypt('xx' + password) == 'crypted string') then
     password is ok
endif

В наши дни crypt() является эквивалентом безопасности кольца декодера зерновых ящиков. Там для исторических целей и низкой безопасности "кто волнуется, если он треснул в" хранилище. Для любого современного использования паролей вам будет лучше использовать более современные хеши, например sha1/sha256/md5. И даже md5 считается сломанным в эти дни, sha1 имеет трещины по краям, и (последний раз я проверил) sha256 по-прежнему безопасен.

Ответ 2

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

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

Соль должна храниться где-то. Если у вас был эффективный способ сохранить "секрет", почему бы не использовать его для хранения пароля и вообще забыть о хэшировании? Нет; если вам нужна реальная безопасность, вам нужно разработать систему, чтобы быть в безопасности от атаки грубой силы, даже если злоумышленник знает соль. Презумпция статьи о том, что соль может храниться в секрете, должна рассматриваться как false.

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

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

Ответ 3

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

Смотрите:

Как вы используете bcrypt для хеширования паролей в PHP?

http://uk.php.net/manual/en/function.crypt.php

http://www.openwall.com/phpass/

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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