那么,我应该如何在postgresql中哈希(带有某些盐)密码呢?
我问这个问题已经有一段时间了,现在我对加密理论更加熟悉,所以这是更现代的方法:
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)
// 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)
使用随机盐值对 :password 进行哈希:
insert into accounts (password) values crypt(:password, gen_salt('bf', 8));
//(the 8 is the work factor)
在php 5.5及以上版本中有password_*
函数可允许使用bcrypt进行极其简单的密码哈希(终于!),对于低版本的php也有一个向后兼容的库。通常情况下会回退到包装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在5.3.0到5.3.6.9版本中的实现略有缺陷,并且在php 5.2.9及更低版本中不合适地回退到破损的DES
而没有任何警告。
如果您想/需要在postgresql中进行哈希,请安装bcrypt,因为默认安装的哈希值已经过时且易受攻击(例如md5)。
以下是有关此主题的更多阅读参考:
应用程序应使用诸如bcrypt或pbkdf2之类的密钥派生函数来哈希其密码。这里提供了更多关于安全密码存储的信息。
...但有时候数据库仍需要加密功能。
您可以使用pgcrypto来访问sha256,它是sha2家族的成员。请记住,sha0、sha1、md4和md5非常不安全,绝不能用于密码哈希。
下面是一种不错的密码哈希方法:
digest("salt"||"password"||primary_key, "sha256")
盐值应该是一个大的随机生成的值。必须保护这个盐值,因为在盐值恢复之前无法破解哈希。如果您将盐值存储在数据库中,则可以使用SQL注入获取它以及密码哈希。使用主键连接可以防止两个人具有相同的密码哈希,即使他们使用相同的密码。当然,这个系统可以改进,但比我看到的大多数系统都要好得多。
通常最好在应用程序中进行哈希处理,然后再将其传递给数据库。这是因为查询可能会出现在日志中,如果数据库服务器被拥有,则可以启用日志记录以获取明文密码。
有关示例和文档: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 ... ;
digest
函数来加密密码,它不够安全。只需确保使用Blowfish算法而不是MD5即可。 - GetFree
password_hash()
。Bcrypt是密码哈希的最新技术,因此它比其他选项(无论是在postgresql还是php中)都更好。Bcrypt哈希是有意设计为资源密集型的,因此如果您在php中使用它,请尝试从crypt()中获取bcrypt以减少服务器的资源使用。 - Kzqaiscram-sha-256
密码方案(来自RFC 7677)。由于它使用了SCRAM,在某些情况下,它可能是PHP的password_*
函数的替代方案。 - Code4R7