我怎样才能哈希密码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 ... ;