PHP crypt() 返回错误答案

发布于 2024-10-21 12:42:16 字数 1485 浏览 1 评论 0原文

我想我在这里失去了理智......我的网站遇到了一个问题,它随机停止接受登录。我现在已经能够追踪到 crypt() 的行为非常奇怪。

在我的数据库中,我有用户密码的加密版本 - 所以假设是 Og12345678。

当用户登录时,他们输入密码,我从数据库中读取盐,然后加密他们输入的内容并进行比较 - 通常这效果很好。

所以我正在做 crypt($enteredPassword, $saltFromDb) - 在这种情况下,盐当然是 Og。通常对于给定的用户密码加密工作正常。

当出现问题时(当出现问题时,这是一个永久性的更改,直到我重新启动 Apache)我发现 crypt 开始为具有相同盐的相同输入返回不同的答案。

然而,它是一致的,即一旦系统出错,crypt就会返回错误的答案,但它总是返回相同的错误答案。重复刷新页面会显示相同的输出。同样的盐也出现在新的错误的地穴结果中,所以并不是说盐在某个地方丢失了。

如果我随后重新启动 Apache 并重新运行脚本而不做任何更改,那么 crypt 的结果就会恢复到应有的样子。

我很欣赏它不是最新的 PHP (5.2.8),但会重视对此的任何看法,包括是否是在更高版本中修复的已知错误(升级 PHP 并不是一项愉快的任务,因为许多网站仍然使用不幸的怪癖,每次升级都需要重新测试) - 如果这是一个已知的已修复错误,那么显然我会尽快将其全部升级,除此之外,将地穴外包到外部可能会更容易,因为我只在一个中使用它我的网站的常见位置。

任何意见表示赞赏。

Matt Peddlesden

--- 更新:2011 年 3 月 11 日

更正之前给出的有关操作系统的评论... - 操作系统是 Windows Server 2008 SP1 64 位。抱歉,我应该仔细检查一下,而不是假设我记得!机器是 Dell 2950 8gb Ram、Xeon 处理器。

我开始沿着 Krtek 的建议思考 - 当系统变得不稳定时,如果我生成新的 crypt() (即一个非常简单的示例,其中我将变量设置为字符串,对其进行加密,然后与地穴进行比较) - 一切都很好。当我重新启动服务器时,一切又回到了之前的计算。所以我肯定倾向于改变用于计算 crypt() 结果的算法......对于可能导致这种情况发生的任何想法?我打印了 CRYPT_STD_DES 等的值,它们在重新启动之间不会改变。

有人知道什么可能导致这种情况发生吗?

不管是什么,昨天似乎一天之内发生了两次,最奇怪的是。

感谢迄今为止的回答。

--- 更新:2011 年 3 月 16 日

只是想提供另一个更新。

这种情况仍在发生,仍然没有进一步了解原因。

如果将来有人遇到这种情况,我认为我的解决方案将是进行一些令人讨厌的 hack,将所有 crypt() 执行推送到外部 C# 应用程序,而不必依赖 PHP 来完成它们。某处出了问题,此时我能看到的唯一解决方案是将其完全从方程中删除。

当然,如果它仍然发生,知道这一点也会很有趣! :)

谢谢大家。

I think i'm losing my marbles here... I've got a problem on my web site where randomly it stops accepting logins. I've now been able to trace it to crypt() behaving very strangely.

In my database, i've got the crypted version of the users password - so let's say Og12345678.

When the user logs in, they enter their password, I read the salt out of the db and then crypt what they entered and compare - usually this works very well.

So i'm doing crypt($enteredPassword, $saltFromDb) - in this case, the salt would be Og of course. Normally for a given users password crypt works fine.

When things go wrong (and when they do it's a permanent change until I restart Apache) I found that crypt starts returning a DIFFERENT answer for the same input with the same salt.

It's consistent however, i.e. once the system has gone wrong crypt returns the wrong answer but it's always returning the same wrong answer. Repeated refreshes of the page show the same output. The same salt is also in evidence in the newly incorrect crypt result also, so it's not that the salt has gone missing somewhere.

If I then restart Apache and re-run the script without any changes at all, the results from crypt are then back to how they should be.

I appreciate it's not the latest PHP (5.2.8) but would value any views on this including whether it's a known bug fixed in a later version (upgrading PHP is not a happy task with lots of sites some of which still use unfortunate quirks that all need to be re-tested with each upgrade) - if it is a known fixed bug then obviously i'll get it all upgraded ASAP, beyond that it'll probably be easier to outsource the crypt externally since I only use it in one common place for my site.

Any input appreciated.

Matt Peddlesden

--- Update: 11 Mar 2011

Correction to comment previously given about operating system...
- Operating system is Windows Server 2008 SP1 64 bit. Apologies I should have double checked rather than assuming I could remember! Machine is a Dell 2950 8gb Ram, Xeon processors.

I am starting to think along the lines Krtek is suggesting - when the system has gone wonky, if I generate new crypt() (i.e a very simple example where i set a variable to a string, crypt it and then compare with the crypt) - all works great. When I restart the server, again it's all back to the previous calculations again. So I am definitely leaning towards something that is changing the algorithm used to calculate the crypt() result... any thoughts on what might cause this to happen? I printed out the values of the CRYPT_STD_DES etc and they don't change between restarts.

Anyone got any clues on what might cause this to happen?

Whatever it was seemed to happen twice in one day yesterday, most odd.

Thanks for the answers thus far.

--- Update: 16 Mar 2011

Just wanted to provide another update.

This is still happening, still no further understanding of why.

In case anyone comes across this in the future, I think my solution going forwards is going to be to do some nasty hack to push all the crypt() executions out to an external C# application and stop having to rely on PHP to do them. Something is going wrong somewhere and at this point the only solution I can see is to remove it from the equation entirely.

Of course if it still happens, that will be interesting to know too! :)

Thanks all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寂寞笑我太脆弱 2024-10-28 12:42:16

你为什么读盐?你怎么得到盐?不同的算法使用不同的方法在输出中包含盐。

只需使用 crypt 函数的整个输出作为第二个参数:

  $crypted='Og12345678';
  if (crypt($_POST['password'], $crypted)==$crypted) {
      ....

单通道 DES?真的吗?

上次我查看时,PHP crypt 实现将调用系统提供的 crypt() 函数 - 所以如果它损坏了,那么它更有可能是你的操作系统而不是 PHP - 但你没有说你的操作系统是什么。

Why are you reading the salt? And how are you getting the salt? Different algorithms use different methods for including the salt in the output.

Just use the whole output of the crypt function as the second argument:

  $crypted='Og12345678';
  if (crypt($_POST['password'], $crypted)==$crypted) {
      ....

And single pass DES? Really?

Last time I looked, the PHP crypt implementation would call the crypt() function provided by the system - so if it has broekn then its more likely to be your OS than PHP - but you didn't say what your OS is.

℡Ms空城旧梦 2024-10-28 12:42:16

这可能是 Suhosin PHP 安全补丁影响了您的 crypt() 函数。它改变了很多加密/随机方法,可能是问题的原因。

检查 phpinfo() 并查看“suhosin”是否在页面上的任何位置。如果存在,请考虑在 php 配置中禁用它的某些功能。

It might be the Suhosin PHP security patch affecting your crypt() function. It alters a lot of the encryption/random methods and may be the the cause of your problem.

Check a phpinfo() and see if 'suhosin' is anywhere on the page. If it's there, look into disabling some of it's features in the php config.

寒尘 2024-10-28 12:42:16

我对 crypt 也有同样的问题...我在两台服务器上进行了登录检查,但是当我将其转移到最新的服务器时,它最终停止工作。我使用 md5 加密来绕过它,如下所示:
在register.php

 $encrypted = md5($_POST["pass"]);
 ...

然后在login.php

$password = md5($_POST["password"]);
 if ($password == $row["hash"])
        {
            // remember that user's now logged in by storing user's details in session
            $_SESSION["id"] = $row["id"];
            $_SESSION['username'] = $_POST['username'];
            $_SESSION['logged'] = 'Yes';
            // redirect to homepage
            redirect("index.php");
        }

我希望有帮助:)

i had the same problem with crypt... I had that login-check working on 2 servers, but when i transfer it to the newest one it eventually stop working. I walk around it with md5 encryption as follows:
In register.php

 $encrypted = md5($_POST["pass"]);
 ...

And then in login.php

$password = md5($_POST["password"]);
 if ($password == $row["hash"])
        {
            // remember that user's now logged in by storing user's details in session
            $_SESSION["id"] = $row["id"];
            $_SESSION['username'] = $_POST['username'];
            $_SESSION['logged'] = 'Yes';
            // redirect to homepage
            redirect("index.php");
        }

I hope that helps :)

二货你真萌 2024-10-28 12:42:16

我遇到了同样的问题。自从将我的 vTigerCRM 安装移至本地计算机后,使用先前存储的密码的用户登录开始失败。看起来 crypt() 在具有相同参数的不同环境中返回不同的哈希值:

在本地环境上:

SYSTEM: Windows NT 6.1 build 7601 (Business Edition Service Pack 1) i586
PHP: 5.3.5

crypt('hello world','$1$ad0000000'):

     $1$ad00000008tTFeywywdEQrAl9QzV.M1

在生产环境上:

SYSTEM: Linux 2.6.18-338.9.1.el5.lve0.8.32 #1 x86_64
PHP: 5.3.5

crypt('hello world','$1$ad0000000'):

    $1$ad000000$8tTFeywywdEQrAl9QzV.M1

I faced the same problem. Since moving my vTigerCRM installation to local machine, user login with previously stored passwords started failing. It seems like crypt() is returning different hashes on different environments with the same arguments:

On local environment:

SYSTEM: Windows NT 6.1 build 7601 (Business Edition Service Pack 1) i586
PHP: 5.3.5

crypt('hello world','$1$ad0000000'):

     $1$ad00000008tTFeywywdEQrAl9QzV.M1

On production environment:

SYSTEM: Linux 2.6.18-338.9.1.el5.lve0.8.32 #1 x86_64
PHP: 5.3.5

crypt('hello world','$1$ad0000000'):

    $1$ad000000$8tTFeywywdEQrAl9QzV.M1
眼波传意 2024-10-28 12:42:16

也许这对某人有帮助..

对我来说,问题是我忘记包含这段代码:

if (!defined('PASSWORD_BCRYPT')) {
/**
 * PHPUnit Process isolation caches constants, but not function declarations.
 * So we need to check if the constants are defined separately from 
 * the functions to enable supporting process isolation in userland
 * code.
 */
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
}

Maybe this helps someone..

For me the problem was that i forgot to include this code:

if (!defined('PASSWORD_BCRYPT')) {
/**
 * PHPUnit Process isolation caches constants, but not function declarations.
 * So we need to check if the constants are defined separately from 
 * the functions to enable supporting process isolation in userland
 * code.
 */
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文