如何在 postgresql 中哈希密码?

发布于 2024-08-29 05:02:34 字数 110 浏览 6 评论 0原文

我需要在 postgresql 上用 salt 对一些密码进行哈希处理,但我找不到任何有关如何完成此操作的相关文档。

那么如何在 postgresql 中对密码(带有一些盐)进行哈希处理呢?

I need to hash some passwords with salt on postgresql, and I haven't been able to find any relevant documentation on how to get that done.

So how can I hash passwords (with some salts) in postgresql?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终止放荡 2024-09-05 05:02:34

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

推理

  • 不要使用 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()

将 :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)

From-in- PHP bcrypt 散列稍微好一些

php 5.5 及更高版本中有 password_* 函数允许使用 bcrypt 进行简单的密码散列(大约是时候了!),并且有一个针对低于该版本的向后兼容库。 通常,散列会回退到包装 Linux 系统调用以降低 CPU 使用率,尽管您可能希望确保它安装在您的服务器上。请参阅:https://github.com/ircmaxell/password_compat(需要 php 5.3.7+)

小心请

注意,使用 pg_crypto,密码在从浏览器传输到 php、再到数据库的过程中都是明文形式。这意味着如果您不小心处理数据库日志,它们可能会以明文形式从查询中记录下来。例如,拥有 postgresql 慢查询日志可以捕获并记录正在进行的登录查询中的密码。

总结

如果可以的话,使用 php bcrypt,它将减少密码保持未散列状态的时间。尝试确保您的 Linux 系统的 crypt() 中安装了 bcrypt,以便提高性能。强烈建议至少升级到 php 5.3.7+,因为 php 的实现从 php 5.3.0 到 5.3.6.9 略有问题,并且在 php 5.2.9 中不恰当地回退到损坏的 DES 且没有警告并更低。

如果您想要/需要 in-postgres 散列,安装 bcrypt 是可行的方法,因为默认安装的散列是旧的且损坏的(md5 等)。

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

It's been a while since I asked this question, and I'm much more familiar with the cryptographic theory now, so here is the more modern approach:

Reasoning

  • Don't use md5. Don't use a single cycle of sha-family quick hashes. Quick hashes help attackers, so you don't want that.
  • Use a resource-intensive hash, like bcrypt, instead. Bcrypt is time tested and scales up to be future-proof-able.
  • Don't bother rolling your own salt, you might screw up your own security or portability, rely on gen_salt() to generate it's awesome unique-to-each-use salts on it's own.
  • In general, don't be an idiot, don't try to write your own homegrown crypto, just use what smart people have provided.

Debian/Ubuntu install packages

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)

Activate crypt() and bcrypt in postgresql in your database

// 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

Use crypt() and gen_salt() in queries

Compare :pass to existing hash with:

select * from accounts where password_hash = crypt(:pass, password_hash);
//(note how the existing hash is used as its own individualized salt)

Create a hash of :password with a great random salt:

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

From-in-Php bcrypt hashing is slightly preferrable

There are password_* functions in php 5.5 and above that allow trivially simple password hashing with bcrypt (about time!), and there is a backward compatibility library for versions below that. Generally that hashing falls back to wrapping a linux system call for lower CPU usage anyway, though you may want to ensure it's installed on your server. See: https://github.com/ircmaxell/password_compat (requires php 5.3.7+)

Be careful of logging

Note that with pg_crypto, the passwords are in plaintext all during the transmission from the browser, to php, to the database. This means they can be logged in plaintext from queries if you're not careful with your database logs. e.g. having a postgresql slow query log could catch and log the password from a login query in progress.

In Summary

Use php bcrypt if you can, it'll lessen the time that the password remains unhashed. Try to ensure your linux system has bcrypt installed in it's crypt() so that is performant. Upgrade to at least php 5.3.7+ is highly recommended as php's implementation is slightly buggy from php 5.3.0 to 5.3.6.9, and inappropriately falls back to the broken DES without warning in php 5.2.9 and lower.

If you want/need in-postgres hashing, installing bcrypt is the way to go, as the default installed hashes are old and broken (md5, etc).

Here are references for more reading on the topic:

北方的韩爷 2024-09-05 05:02:34

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

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

您可以使用 pgcrypto 来访问 sha256,它是 sha256 的成员sha2家族。请记住,sha0、sha1、md4 和 md5 非常脆弱,永远不应该用于密码哈希。

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

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

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

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

An application should hash its passwords using key derivation function like bcrypt or pbkdf2. Here is more information on secure password storage.

... but sometimes you still need cryptogrpahic functions in a database.

You can use pgcrypto to get access to sha256 which is a member of the sha2 family. Keep in mind sha0,sha1 md4, and md5 are very broken and should never be used for password hashes.

The following is an alright method of hashing passwords:

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

The salt should be a large randomly generated value. This salt should be protected, because the hashes cannot be broken until the salt is recovered. If you are storing the salt in the database then it can be obtained along with the password hash using sql injection. Concatenating the primary key is used to prevent 2 people from having the same password hash even if they have the same password. Of course this system could be improved, but this is much better than most systems I have seen.

Generally it is best to do hashing in your application before it hits the database. This is because querys can show up in logs, and if the database server was owned then they could enable logging to get clear text passwords.

旧人哭 2024-09-05 05:02:34

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

Examples and documentation on: 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 ... ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文