PHP password_hash()与Postgres crypt()

时间:2014-01-02 05:03:14

标签: php postgresql passwords

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

我正在尝试决定放置用户身份验证逻辑的位置。

我不是安全专家;但是,我熟悉PHP的新password_*()函数,并且我非常了解幕后发生的事情。我也熟悉Postgres扩展pgcrypto和相关的crypt()函数。

我的问题是,使用PHP或Postgres散列密码是否有意义?

我很好奇这些函数是如何不同的,所以我在PHP中创建了一个密码哈希,然后把它交给Postgres看看Postgres是否使用相同的算法。给定相同的参数,与PHP相比,Postgres返回了不同的结果(不出意外,但有注意)。

PHP

password_hash('password', PASSWORD_BCRYPT, ["cost" => 15]);

输出 $ 2y $ 15 $ o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu

的Postgres

SELECT '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu' = crypt('password', '$2y$15$o8JufrnVXoob2NKiEGx6.uI4O2D4VcaAmY7WtNq5zPFiJow4KohGu')

输出 false


PHP vs. Postgres

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

其他一些想法:

我目前拥有存储在数据库中的所有逻辑(视图,函数,约束等),所以如果我需要使用不同的前端,我不必担心缺少逻辑。在PHP中计算密码哈希将有效地要求所有请求通过PHP来访问数据库。

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

我在这里走在正确的轨道上吗?我错过了什么?


修改

我只是看了another message thread并找到了更多信息。

  1. 将逻辑放在Postgres中需要数据库处理并执行散列操作。对于需要这些资源的其他用户和批处理作业来说,这将是一件坏事。
  2. 哈希不仅会减慢正常操作,还会使整个系统更容易受到DOS攻击。
  3. 我们的简单Web服务器具有负载平衡功能,可解决这两个问题......

    再一次,我在这里走在正确的轨道上吗?我还缺少什么?

1 个答案:

答案 0 :(得分:3)

有关版本2y2a之间的区别,请参阅此主题及其中的各个链接:

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

我的理解是PHP until v.5.3.8中的2a实现存在问题,但仅适用于包含非ascii字符的字符串。正如你所指出的那样,PgCrypto由于某种原因不会“说”2y,我认为它会遭遇如此严重的问题。 (也许将此报告为错误?)

除了后者提出的要点之外,你在你的问题中确定了两者之间的主要安全差异:系统地在数据库中散列密码很方便,但暗示你以明文形式将它发送到数据库,它可以在(如果您的数据库连接未加密,则会被记录 - 或者直接窥探。

在理想的世界中,您甚至在发送到PHP之前,使用javascript在客户端应用中对密码进行哈希处理。接下来最好的事情是使用SSL将其发送到PHP,然后使用PHP对其进行哈希处理,然后再将其发送到数据库。

除此之外:如果由于某种原因需要互操作性,我很确定PHP的crypt可以生成(安全)2a版本哈希。