PHP password_hash() 与 Postgres crypt()

los*_*rse 5 php passwords postgresql

我使用Postgres 9.3数据库作为 Web 应用程序的后端。我使用PHP 5.5.7连接到数据库并为前端 AJAX 调用返回 JSON。

我正在尝试决定将用户身份验证逻辑放在哪里。

我不是安全专家;然而,我熟悉 PHP 的新password_*()功能,并且对幕后发生的事情有很强的把握。我也熟悉 Postgres 扩展pgcrypto和相关crypt()功能。

我的问题是,使用 PHP 或 Postgres 来哈希密码是否有意义?

我很好奇这些函数有何不同,所以我用 PHP 做了一个密码哈希,然后将其交给 Postgres,看看 Postgres 是否使用相同的算法。给定相同的参数,Postgres 与 PHP 相比返回了不同的结果(这并不意外,但需要注意)。

PHP

password_hash('password', PASSWORD_BCRYPT, ["cost" => 15]);
Run Code Online (Sandbox Code Playgroud)

输出: $2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu

Postgres

SELECT '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu' = crypt('password', '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu')
Run Code Online (Sandbox Code Playgroud)

输出:


PHP 与 Postgres

鉴于这些过程不同,我想知道是否一个比另一个更好?多一个还是少一个安全?

其他一些想法:

我目前将所有逻辑存储在数据库中(在视图、函数、约束等中),因此如果我需要使用不同的前端,我不必担心丢失逻辑。在 PHP 中计算密码哈希实际上要求所有请求都通过 PHP 来访问数据库。

另一方面,将逻辑放入数据库将使我能够灵活地使用其他连接选项;但是,所有 Postgres 查询都会被记录。由于复制中使用了 WAL,我无法禁用日志。这似乎是一个很大的安全漏洞。

我走在正确的轨道上吗?我缺少什么?


编辑

我刚刚查看了另一个消息线程并找到了更多信息。

  1. 将逻辑放入 Postgres 中需要数据库处理并执行哈希运算。对于需要这些资源的其他用户和批处理作业来说,这将是一件坏事。
  2. 散列不仅会减慢正常操作,还会使整个系统更容易受到 DOS 攻击。

我们具有负载平衡功能的简单 Web 服务器可以解决这两个问题......

再说一次,我走在正确的道路上吗?我还缺少什么?

Den*_*rdy 3

2y对于版本和版本之间的差异2a,请参阅此线程及其中的各个链接:

\n\n

https://security.stackexchange.com/questions/20541/insecure-versions-of-crypt-hashes

\n\n

我的理解是,在 v.5.3.8 之前2a,PHP 中的实现存在问题,尽管仅适用于包含非 ascii 字符的字符串。正如您所指出的,PgCrypto 不会“说话”2y,我认为它会遇到这样的问题。(也许将此报告为错误?)

\n\n

除了后者提出的观点之外,您还指出了问题中两者之间的主要安全差异:在数据库中系统地散列密码很方便,但这意味着您以明文形式将其发送到数据库,在那里它可以(并且将如果您的数据库连接未加密,则将被记录 \xe2\x80\x94 或直接窥探。

\n\n

在理想情况下,您可以在将密码发送到 PHP 之前使用 JavaScript 在客户端应用程序中对密码进行哈希处理。下一个最好的办法是使用 SSL 将其发送到 PHP,然后使用 PHP 对其进行哈希处理,然后再将其发送到数据库。

\n\n

旁白:我非常确定 PHPcrypt可以生成(安全的)2a如果您出于某种原因需要互操作性,

\n