Как я могу хэшировать пароли в postgresql? - PullRequest
45 голосов
/ 15 апреля 2010

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

Так как я могу хэшировать пароли (с некоторыми солями) в postgresql?

Ответы [ 3 ]

74 голосов
/ 08 сентября 2013

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

Рассуждения

  • Не используйте MD5. Не используйте один цикл быстрых хэшей семейства Ша. Быстрые хэши помогают злоумышленникам, так что вы этого не хотите.
  • Вместо этого используйте ресурсоемкий хеш, такой как bcrypt. Bcrypt проверен временем и масштабируется, чтобы соответствовать требованиям будущего.
  • Не утруждайте себя своей собственной солью, вы можете испортить свою собственную безопасность или переносимость, полагайтесь на gen_salt (), чтобы генерировать его уникальные уникальные соли для каждого.
  • В общем, не будь идиотом, не пытайся написать свое собственное доморощенное крипто, просто используй то, что предоставили умные люди.

Установочные пакеты Debian / Ubuntu

sudo apt-get install postgresql   // (of course)
sudo apt-get install postgresql-contrib libpq-dev   // (gets bcrypt, crypt() and gen_salt())
sudo apt-get install php5-pgsql   // (optional if you're using postgresql with php)

Активируйте crypt () и bcrypt в postgresql в вашей базе данных

// Create your database first, then:
cd `pg_config --sharedir` // Move to the postgres directory that holds these scripts.
echo "create extension pgcrypto" | psql -d yOuRdATaBaSeNaMe // enable the pgcrypo extension

Использовать crypt () и gen_salt () в запросах

Сравнить: перейти к существующему хешу с:

select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)

Создать хеш: пароль с большой случайной солью:

insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)

Хеширование bcrypt из-в Php немного предпочтительнее

В php 5.5 и выше есть password_* функции, которые позволяют тривиально простое хеширование паролей с помощью bcrypt (о времени!), И есть версия с обратной совместимостью для версий ниже этого. Обычно это хэширование сводится к обертыванию системного вызова linux для более низкой загрузки ЦП, хотя вы, возможно, захотите убедиться, что оно установлено на вашем сервере. См .: https://github.com/ircmaxell/password_compat (требуется php 5.3.7 +)

Будьте осторожны при регистрации

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

В итоге

Используйте php bcrypt, если можете, это уменьшит время, в течение которого пароль остается не хэшированным. Постарайтесь убедиться, что в вашей системе Linux установлен bcrypt в crypt(), чтобы он работал. Настоятельно рекомендуется обновление до версии не ниже php 5.3.7+, так как реализация php слегка глючит с php 5.3.0 до 5.3.6.9 и ненадлежащим образом возвращается к сломанному DES без предупреждения в php 5.2.9 и ниже. *

Если вы хотите / нуждаетесь в хэшировании в postgres, установка bcrypt - это путь, так как установленные хеши по умолчанию старые и неработающие (md5 и т. Д.).

Вот ссылки для дополнительного чтения по теме:

16 голосов
/ 15 апреля 2010

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

... но иногда вам все еще нужны криптографические функции в базе данных.

Вы можете использовать pgcrypto , чтобы получить доступ к sha256, который является членом семейства sha2. Имейте в виду, что sha0, sha1 md4 и md5 очень повреждены и должны никогда использоваться для хэшей паролей

Ниже приведен способ хэширования паролей:

digest("salt"||"password"||primary_key, "sha256")

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

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

8 голосов
/ 15 апреля 2010

Примеры и документация по: http://www.postgresql.org/docs/8.3/static/pgcrypto.html

UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));

SELECT pswhash = crypt('entered password', pswhash) FROM ... ;
...