Почему PHP crypt () добавляет соль в хеш? - PullRequest
11 голосов
/ 26 января 2011

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

пример:

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

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

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

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

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

Ответы [ 6 ]

29 голосов
/ 26 января 2011

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

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

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

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

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

9 голосов
/ 07 апреля 2012

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

См .:

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

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

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

3 голосов
/ 26 января 2011

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

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

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

1 голос
/ 26 января 2011

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

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

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

1 голос
/ 26 января 2011

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

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

1 голос
/ 26 января 2011

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

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 по-прежнему безопасен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...