Postgresql 使用数据库功能执行用户身份验证的更快方法

Postgresql 使用数据库功能执行用户身份验证的更快方法,postgresql,authentication,password-encryption,sql-execution-plan,Postgresql,Authentication,Password Encryption,Sql Execution Plan,是否有一种更快的方法可以使用数据库功能对用户进行安全身份验证? crypt()函数似乎花费了很多时间 表: id (bigserial) pkey username (text) indexed password (text) indexed [password is the hash: crypt('12345678', gen_salt('bf', 8))] 普通测试: test_db=# explain analyze SELECT id FROM users WHERE id = 1

是否有一种更快的方法可以使用数据库功能对用户进行安全身份验证? crypt()函数似乎花费了很多时间

表:

id (bigserial) pkey
username (text) indexed
password (text) indexed [password is the hash: crypt('12345678', gen_salt('bf', 8))]
普通测试:

test_db=# explain analyze SELECT id FROM users WHERE id = 1 AND password='12345678' LIMIT 1;
                                                                QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.28..8.29 rows=1 width=8) (actual time=0.029..0.029 rows=0 loops=1)
   ->  Index Scan using users_idx_password01 on users  (cost=0.28..8.29 rows=1 width=8) (actual time=0.028..0.028 rows=0 loops=1)
         Index Cond: (password = '12345678'::text)
         Filter: (id = 1)
 Total runtime: 0.037 ms
(5 rows)
Crypt()测试:


我不完全确定postgres是如何处理这样一个查询的,但在我看来,crypt函数是为每一行执行的。当您考虑使用适当的密码哈希函数时,它的目的是慢的,这样的查询每行都会变慢。 处理此类查询的方法是,仅搜索用户,然后验证密码哈希:

SELECT password FROM users WHERE username = "carfield"
然后在代码中测试找到的密码散列。这还允许为每个密码处理唯一的密码,这是必须具备的。合适的散列函数是BCrypt、PBKDF2或SCrypt,它们都有一个成本因子。编程环境通常已经提供函数,这是PHP中的一个示例:

$isPasswordCorrect = password_verify($password, $existingHashFromDb);

从设计上看,不是。缓慢是一个特性,而不是一个bug。看见此外,您所说的每个查询的差异只有几毫秒,一个用户不一定会注意到。是的,在一个同时尝试多次登录的系统中(例如,这可能会导致拒绝服务攻击),但加快哈希并不是解决问题的方法。感谢Andrew,您正确地解决了这个问题:每个请求都需要经过身份验证,并且并发性要适度(200 req/sec)服务器没有响应。在这一点上,我正在考虑升级和拆分硬件。谢谢,谢谢!平均快33%。经过一些调查,似乎不是每个记录都执行crypt()函数,这是postgres/pgcrypto库处理调用的方式,比php实现慢。我错误地认为让DB管理身份验证更健壮/快速。@DPZ-有趣的是,PHP有一个带函数的BCrypt本机实现。快速实现允许增加成本因素,这当然有利于安全性。
$isPasswordCorrect = password_verify($password, $existingHashFromDb);