我在PHP的“crypt()”中找到了一个错误吗?

时间:2010-04-23 15:06:40

标签: php encryption

我想我可能在Windows下的PHP crypt()函数中发现了一个错误。

然而:我认识到可能是我的错。数以百万计的PHP使用PHP并且成千上万;我的代码被数十使用并由我工作。 (这个论点最好explained on Coding Horror。)

所以我正在寻求帮助:告诉我我的错。我一直试图找几天,没有运气。

设置

我正在使用Apache 2.2.14(Win32)和PHP 5.3.2的Windows服务器安装。我的开发盒运行Windows XP Professional; “生产”服务器(这是一个Intranet设置)运行Windows Storage Server 2003.两者都会出现问题。

我在php.ini中没有看到与crypt()相关的任何内容,但很乐意回答有关我的配置的问题。

问题

我的PHP应用程序中的几个脚本偶尔会挂起:页面位于'等待本地主机'并且永远不会完成。这些脚本中的每一个都使用crypt在将用户密码存储到数据库之前对其进行哈希处理,或者在登录页面的情况下,在将输入的密码与存储在数据库中的版本进行比较之前对其进行哈希处理。

由于登录页面最简单,我专注于测试。我反复登录,发现它可能会挂起10次中的4次。

作为一项实验,我更改了登录页面以使用纯文本密码,并将数据库中的密码更改为纯文本版本。页面停止了。

我看到PHP的最新版本列出了这个错误修正:

  

修正了错误#51059(地址崩溃时崩溃了   无效盐是[原文如此]。

所以我使用an official example中给出的相同的盐创建了一个非常简单的测试脚本,如下所示:

$foo = crypt('rasmuslerdorf','r1');
echo $foo;

如果我像疯了一样重装它,这个页面也会挂起。我只是看到它挂在Chrome中,但无论浏览器如何,对Apache的影响都是一样的。

对Apache的影响

当这些页面挂起时,Apache的server-status page(我解释here,关于另一个问题)增加了正在处理的请求数量并减少了空闲工作者的数量。处理的请求几乎都具有“发送回复”的状态,但有时他们会显示“阅读请求”或“保持活跃(阅读)”。

最终, Apache可能会崩溃。如果是这样,Windows崩溃报告如下所示:

szAppName: httpd.exe
szAppVer: 2.2.14.0
szModName: php5ts.dll
szModVer: 5.3.1.0 // OK, this report was before I upgraded to PHP 5.3.2, 
                  // but that didn't fix it
offset: 00a2615

这是我的错吗?

我很想向PHP提交错误报告。如上所述,反对它的论点是错误几乎总是我的错。

然而,我支持'这是PHP的错误'的论点是:

  1. 我正在使用Windows,而大多数服务器都使用Linux(我不会选择这个),所以我发现边缘情况的可能性更大
  2. 最近有crypt()的错误,所以可能还有问题
  3. 我做了最简单的测试用例,我仍然遇到了问题
  4. 任何人都可以复制这个吗?你能说明我哪里出错吗?我毕竟应该提交错误吗?

    提前感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:4)

错误51059(仅关于传递无效输入)或50947(不是相同的代码,5.3具有在PHP中实现的新算法和功能,在所有平台上)与此问题无关。

然而http://bugs.php.net/bug.php?id=51424是。我已经在那里发布了一个部分补丁,但它解决了大多数可能的锁,但它确实不够。完整修复将出现在下一个5.3版本中。

顺便说一下,它不是特定于Windows的,而是关于线程化的SAPI(例如windows apache 2.2)。

答案 1 :(得分:2)

这个问题现已被观看了128次并被投票了9次。我收到的唯一答案是它是一个bug,并指向PHP bug数据库中的一个。我不认为它完全相同,但似乎确实证实了我的诊断。

因此,有些犹豫,我提交了一份错误报告:

Bug #51666 - Using crypt() makes Apache hang or crash

感谢所有与我一起看过这个问题的人 - 即使你没有回复,只要知道别人正在考虑这件事,而不是告诉我我疯了,一直都很有帮助。

答案 2 :(得分:1)

是。这是一个已知的错误,

http://bugs.php.net/bug.php?id=50947

您可以使用mcrypt模拟crypt()结果。如果您可以更改密码哈希,那么您应该使用hash_hmac(),这样更安全,我们在Apache上没有任何问题。虽然在Windows上没有经验。