Каков рекомендуемый способ шифрования паролей пользователей в базе данных? - PullRequest
17 голосов
/ 07 января 2010

В веб-приложении, написанном на Perl и использующем PostgreSQL, пользователи имеют имя пользователя и пароль. Какой рекомендуемый способ хранения паролей?

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

Есть ли в PostgreSQL встроенный способ сделать это?

Должен ли я использовать Дайджест :: MD5 ?

Ответы [ 7 ]

29 голосов
/ 08 января 2010

Не используйте SHA1 или SHA256 , как предлагает большинство других людей. Определенно не используйте MD5 .

SHA1 / 256 и MD5 предназначены для создания контрольных сумм файлов и строк (и других типов данных, если это необходимо). Из-за этого они разработаны так, чтобы быть максимально быстрыми, чтобы можно было быстро генерировать контрольную сумму.

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

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

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

Мне лично нравится bcrypt. Должна быть доступна версия на Perl, так как быстрый поиск в Google дал несколько возможных совпадений.

17 голосов
/ 07 января 2010

MD5 обычно используется, но SHA1 / SHA256 лучше. Все еще не лучший, но лучший.

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

Но вы хотите максимально замедлить атакующего, не так ли? Не лучше ли использовать алгоритм, который вместо хэширования пароля занимает одну десятую секунды? Десятая доля секунды все еще достаточно быстра, чтобы пользователи обычно этого не замечали, но злоумышленник, у которого есть копия вашей базы данных, сможет делать только 10 попыток в секунду - им потребуется 100 000 раз больше, чтобы найти рабочий набор. учетных данных Каждый час, который им потребуется за микросекунду за попытку, становится 11 лет с точностью до одной десятой секунды за попытку.

Итак, как вы этого достигнете? Некоторые люди притворяются, выполняя несколько раундов переваривания MD5 / SHA, но алгоритм bcrypt разработан специально для решения этой проблемы. Я не совсем понимаю математику, стоящую за этим, но мне сказали, что она основана на создании фреймов Blowfish, которые по своей природе медленны (в отличие от операций MD5, которые могут быть сильно оптимизированы на правильно настроенном оборудовании), и имеют настраиваемый параметр «стоимость», чтобы по мере продвижения закона Мура все, что вам нужно было сделать, это отрегулировать эту «стоимость», чтобы хеширование вашего пароля было таким же медленным за десять лет, как и сегодня.

3 голосов
/ 31 декабря 2010

Мне нравится bcrypt лучше всего, с SHA2 (256) за секунду. Я никогда не видел, чтобы MD5 использовался для паролей, но, возможно, некоторые приложения / библиотеки используют это. Имейте в виду, что вы всегда должны также использовать соль. Сама соль должна быть абсолютно уникальной для каждого пользователя и, на мой взгляд, как можно дольше. Я бы никогда не использовал просто хеш против строки без добавления соли. В основном потому, что я немного параноик, а также из-за того, что это более перспективно на будущее.

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

2 голосов
/ 07 января 2010

Модуль pgcrypto в PostgreSQL имеет встроенную поддержку для хэширования паролей, которая довольно умна в отношении хранения, генерации, мульти-алгоритма и т. Д. См. http://www.postgresql.org/docs/current/static/pgcrypto.html, раздел Функции хэширования паролей . Вы также можете увидеть раздел pgcrypto http://www.hagander.net/talks/hidden%20gems%20of%20postgresql.pdf.

0 голосов
/ 07 января 2010

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

0 голосов
/ 07 января 2010

Я бы предложил хранить его как соленый хэш md5.

INSERT INTO user (password) VALUES (md5('some_salt'||'the_password'));

Вы можете вычислить хэш md5 в perl, если хотите, это не имеет большого значения, если вы не оптимизируете микро.

Вы также можете использовать sha1 в качестве альтернативы, но я не уверен, что у Postgres есть собственная реализация этого.

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

Я всегда использую одноразовую случайно сгенерированную соль и сохраняю ее в исходном коде приложения или в файле конфигурации.

Еще одно преимущество использования хэша md5 или sha1 для пароля состоит в том, что вы можете определить столбец пароля как фиксированную ширину CHAR (32) или CHAR (40) для md5 и sha1 соответственно.

0 голосов
/ 07 января 2010

Используйте перемешивание SHA1 или SHA256 с засолкой. Это способ хранения паролей.

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