我需要在 postgresql 上用盐对一些密码进行哈希处理,但我找不到任何有关如何完成此操作的相关文档。
那么如何在 postgresql 中散列密码(带有一些盐)?
我需要在 postgresql 上用盐对一些密码进行哈希处理,但我找不到任何有关如何完成此操作的相关文档。
那么如何在 postgresql 中散列密码(带有一些盐)?
自从我问这个问题以来已经有一段时间了,而且我现在对密码学理论更加熟悉,所以这里是更现代的方法:
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)
// 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
将 :pass 与现有哈希进行比较:
select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)
使用随机盐创建 :password 的哈希:
insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)
php 5.5 及更高版本中有一些password_*
函数允许使用 bcrypt 进行简单的密码散列(大约是时候了!),并且对于低于该版本的版本有一个向后兼容库。 通常,散列会退回到包装 linux 系统调用以降低 CPU 使用率,尽管您可能希望确保它已安装在您的服务器上。请参阅: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 及更低版本中不适当地回退到损坏而没有警告。
如果您想要/需要 in-postgres 散列,安装 bcrypt 是可行的方法,因为默认安装的散列是旧的和损坏的(md5 等)。
以下是有关该主题的更多阅读参考资料:
应用程序应使用 bcrypt 或 pbkdf2 等密钥派生函数对其密码进行哈希处理。 这是有关安全密码存储的更多信息。
...但有时您仍然需要数据库中的密码功能。
您可以使用pgcrypto访问 sha256,它是 sha2 系列的成员。请记住 sha0、sha1 md4 和 md5 非常损坏,不应该用于密码哈希。
以下是哈希密码的好方法:
digest("salt"||"password"||primary_key, "sha256")
盐应该是一个很大的随机生成的值。这种盐应该受到保护,因为在恢复盐之前无法破坏散列。如果您将盐存储在数据库中,则可以使用 sql 注入将其与密码哈希一起获取。连接主键用于防止两个人拥有相同的密码哈希,即使他们拥有相同的密码。当然这个系统可以改进,但这比我见过的大多数系统要好得多。
通常,最好在应用程序访问数据库之前对其进行哈希处理。这是因为查询可以显示在日志中,如果数据库服务器是自己的,那么他们可以启用日志记录以获取明文密码。
示例和文档: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 ... ;