如何在postgresql中哈希密码?

Kzq*_*qai 47 security postgresql hash cryptography salt

我需要在postgresql上使用salt散列一些密码,而且我无法找到有关如何完成这些操作的任何相关文档.

那么如何在postgresql中散列密码(带有一些盐)呢?

Kzq*_*qai 76

我问这个问题已经有一段时间了,现在我对加密理论更加熟悉了,所以这里有更现代的方法:

推理

  • 不要使用md5.不要使用sha-family快速哈希的单个循环.快速哈希可以帮助攻击者,所以你不需要它.
  • 使用资源密集型哈希,例如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)
Run Code Online (Sandbox Code Playgroud)

在数据库的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
Run Code Online (Sandbox Code Playgroud)

在查询中使用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)
Run Code Online (Sandbox Code Playgroud)

创建一个哈希:密码,随机盐很棒:

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

From-in-Php bcrypt哈希值得一提

password_*在PHP 5.5及更高版本中有一些功能允许使用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等).

以下是有关该主题的更多阅读的参考资料:

  • 那么,最好用pgcrypto对应用程序进行散列?一般来说,应该通过pg而不是应用程序来完成例行工作哈希,guid生成等吗?谢谢! (2认同)

roo*_*ook 16

应用程序应使用密钥派生函数(如bcrypt或pbkdf2)对其密码进行哈希处理. 以下是有关安全密码存储的更多信息.

...但有时你仍然需要在数据库中使用cryptogrpahic函数.

您可以使用pgcrypto访问sha256,它是sha2系列的成员.请记住sha0,sha1 md4和md5非常破碎,不能用于密码哈希.

以下是散列密码的好方法:

digest("salt"||"password"||primary_key, "sha256")
Run Code Online (Sandbox Code Playgroud)

盐应该是一个随机生成的大值.这种盐应该受到保护,因为在盐被回收之前,哈希不能被破坏.如果要将salt存储在数据库中,则可以使用sql注入获取密码哈希值.连接主键用于防止2个人拥有相同的密码哈希,即使他们具有相同的密码.当然这个系统可以改进,但这比我见过的大多数系统要好得多.

通常,最好在应用程序到达数据库之前对其进行散列处理.这是因为查询可以显示在日志中,如果拥有数据库服务器,则可以启用日志记录以获取明文密码.

  • pgcrypto页面上的文档非常好,并阐明了为什么这是一种非常愚蠢的哈希方式.事实上,灾难的秘诀.使用crypt函数,改为使用'bf'哈希.在http://codahale.com/how-to-safely-store-a-password/上查看更多内容,包括如何使用几十亿个盐渍哈希进行自定义破解 (5认同)

小智 8

有关以下内容的示例和文档: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 ... ;
Run Code Online (Sandbox Code Playgroud)

  • @Tchalvak正确 - 您不再需要提供自己的盐数据.事实上,gen_salt也对算法进行了编码,正如我在上面提到的那样,它应该是'bf' - 请参阅参考资料.鉴于使用'bf',这个答案远远优于那个车. (3认同)
  • 是的,pgcrypto 看起来像我正在寻找的东西,但是我很难弄清楚用法,示例用法是说我不必将自己的盐硬编码到哈希中吗?即我不再需要提供我自己的盐数据,例如:`update account set pswhash = crypt('global salt' || 'new password' || 'user created date', gen_salt('sha256')) where account_id = 5`?还是腌制仍然是一个手动过程? (2认同)
  • 使用md5算法,没有任何迭代计数(适应散列速度随时间的增加)是灾难的一个方法.相反,使用'bf':gen_salt('bf').在http://codahale.com/how-to-safely-store-a-password/上查看更多内容,包括如何使用几十亿个盐渍哈希进行自定义破解 (2认同)