代码之家  ›  专栏  ›  技术社区  ›  Kzqai

如何在PostgreSQL中散列密码?

  •  44
  • Kzqai  · 技术社区  · 16 年前

    我需要在postgresql上用salt散列一些密码,我还没有找到任何相关的文档来说明如何完成这项工作。

    那么我如何在postgresql中散列密码(加上一些盐)?

    3 回复  |  直到 10 年前
        1
  •  73
  •   Kzqai    10 年前

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

    推理

    • 不要使用MD5。不要使用一个周期的sha家族快速散列。快速散列可以帮助攻击者,所以你不希望这样。
    • 使用资源密集型哈希,例如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)
    

    在数据库的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)
    

    创建一个散列:密码与一个伟大的随机盐:

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

    在php中,bcrypt哈希稍微好一些

    有 password_* php 5.5及以上版本中的函数,允许使用bcrypt进行简单的密码散列(大约是时间!),下面的版本有一个向后兼容库。 一般来说 尽管您可能希望确保它安装在您的服务器上,但散列还是会返回到包装linux系统调用以降低cpu使用率。见: https://github.com/ircmaxell/password_compat (需要PHP5.3.7+)

    小心伐木

    请注意,使用pg_crypto,在从浏览器到php和数据库的传输过程中,密码都是纯文本的。这意味着它们可以被记录 明文 如果不小心处理数据库日志,则执行查询。例如,使用postgresql慢速查询日志可以捕获并记录正在进行的登录查询的密码。

    综上所述

    如果可以,可以使用php bcrypt,这将减少密码未被清除的时间。尝试确保Linux系统中安装了bcrypt crypt() 所以这就是表演。强烈建议至少升级到php 5.3.7+,因为php的实现在php5.3.0到5.3.6.9之间有点小错误,并且不适当地返回到中断的位置。 DES 在php 5.2.9和更低版本中没有警告。

    如果您希望/需要postgres散列,那么安装bcrypt是一种方法,因为默认安装的散列是旧的和损坏的(md5等)。

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

        2
  •  16
  •   Community Mohan Dere    9 年前

    应用程序应该使用密钥派生函数(如bcrypt或pbkdf2)散列其密码。 Here is more information on secure password storage .

    …但有时你仍然需要数据库中的加密函数。

    你可以使用 pgcrypto 进入SHA256,这是SHA2家族的一员。记住sha0,sha1 md4,和md5是非常坏的,应该 从未 用于密码哈希。

    以下是散列密码的正确方法:

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

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

    一般来说,最好在应用程序到达数据库之前对其进行哈希处理。这是因为查询可以显示在日志中,如果数据库服务器是所有的,那么它们可以启用日志以获取明文密码。

        3
  •  8
  •   Igor luckyamit    10 年前

    示例和文档: 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 ... ;
    
    推荐文章