我怎样才能哈希密码postgresql?
我需要在postgresql上使用salt来encryption一些密码,而且我还没有find任何相关的文档来说明如何完成这些工作。
那么我怎样才能在PostgreSQL的哈希密码(与一些盐)?
自从我问这个问题已经有一段时间了,现在我对密码理论更加熟悉了,所以这里是更现代的方法:
推理
- 不要使用md5。 不要使用一个单一的沙族快速哈希循环。 快速哈希帮助攻击者,所以你不想这样做。
- 改为使用资源密集型散列,如bcrypt。 Bcrypt经过时间考验,并且可扩展到可以保证未来的性能。
- 不要打扰你自己的盐,你可能会搞砸你自己的安全性或可移植性,依靠gen_salt()来生成它自己的独特的盐。
- 一般来说,不要成为一个白痴,不要试图编写自己的本土encryption,只是使用聪明的人提供的。
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)
在数据库中激活postgresql中的crypt()和bcrypt
// 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)
用一个很棒的随机盐创build一个哈希密码:
insert into accounts (password) values crypt(:password, gen_salt('bf', 8)); //(the 8 is the work factor)
From-in-Php中的bcrypt散列是稍微可取的
在php 5.5及以上版本中有password_*
函数,允许使用bcrypt进行简单的密码散列(大约是时间!),并且对于低于这个版本的版本有一个向后兼容的库。 通常情况下 ,散列回退到包装Linux系统调用降低CPU使用率,尽pipe您可能要确保它已安装在您的服务器上。 请参阅: https : //github.com/ircmaxell/password_compat (需要php 5.3.7+)
小心伐木
请注意,使用pg_crypto时,在从浏览器到php到数据库的传输过程中密码都是纯文本的。 这意味着,如果您不小心使用数据库日志,则可以使用明文login。 例如有一个postgresql慢速查询日志可以捕获和login正在进行的login查询的密码。
综上所述
如果可以的话,使用php bcrypt,这将减less密码保持不变的时间。 尝试确保你的linux系统在crypt()
安装了bcrypt,这样就可以保证性能。 至less升级到PHP 5.3.7 +强烈推荐,因为PHP的实现是从PHP 5.3.0到5.3.6.9略有bug,并不恰当地回落到破损的DES
没有警告在PHP 5.2.9和更低。
如果你想/需要in-postgres散列,安装bcrypt是要走的路,因为默认安装的哈希是老的和破碎的(md5等)。
以下是有关该主题的更多阅读的参考资料:
应用程序应使用密钥派生函数(如bcrypt或pbkdf2)对其密码进行散列。 以下是有关安全密码存储的更多信息 。
…但有时你仍然需要在数据库中的cryptogrpahic函数。
你可以使用pgcrypto来访问sha256,它是sha2家族的成员。 请记住,sha0,sha1 md4和md5非常破碎, 不应该用于密码散列。
以下是散列密码的一个好方法:
digest("salt"||"password"||primary_key, "sha256")
盐应该是一个很大的随机生成的价值。 这种盐应该受到保护,因为在盐被回收之前不能破碎。 如果你要在数据库中存储盐,那么可以使用sql注入来获得口令哈希值。 连接主键用于防止2个人拥有相同的密码哈希,即使他们有相同的密码。 当然这个系统可以改进,但是这比我见过的大多数系统要好得多。
一般来说,最好在应用程序到达数据库之前进行散列。 这是因为查询可以显示在日志中,并且如果数据库服务器是拥有的,则可以启用日志logging以获得明文密码。
有关示例和文档: 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 ... ;