【问题标题】:PHP password_hash() vs. Postgres crypt()PHP password_hash() 与 Postgres crypt()
【发布时间】:2014-01-02 05:03:13
【问题描述】:

我使用 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')

输出:


PHP 与 Postgres

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

其他一些想法:

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

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

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


编辑

我刚刚查看了another message thread,发现了更多信息。

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

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

再说一遍,我在正确的轨道上吗?我还缺少什么?

【问题讨论】:

  • 你试过两者都用吗? :D
  • @dan - 我认为两者都会为所有问题提供相同的安全性:)

标签: php postgresql passwords


【解决方案1】:

关于版本2y2a 之间的区别,请参阅此线程及其中的各种链接:

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

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

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

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

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

【讨论】:

  • 创建哈希客户端是一个有趣的想法......我看到的问题是,每次尝试验证密码时,我都需要将盐(每个密码唯一且随机)发送到哈希处理的客户端。这似乎是一个问题,因为客户端可以访问所使用的算法和客户端提供的任何用户名的盐。
  • 在客户端散列可能不是一个好主意。 Check out why...
  • @ircmaxell:当我阅读您链接到的文章时,问题在于以安全方式提供加密密钥,这确实是一个问题,但仅适用于双向加密。在对密码进行哈希处理时,您唯一需要的是浏览器本身内的一个好的 RNG,以便生成盐。 (而且我似乎记得 sjcl 有一个。)
  • @losthorse:是的,你的第二组问题是正确的。但是注意ddos的门对于db或者php来说基本是一样的。唯一真正的区别是哪个 cpu 被恶意哈希掠夺。
猜你喜欢
  • 1970-01-01
  • 2013-05-05
  • 2016-12-09
  • 1970-01-01
  • 2014-07-14
  • 2023-04-08
  • 2019-04-25
  • 1970-01-01
  • 2013-11-08
相关资源
最近更新 更多