【问题标题】:mcrypt doesn't work in PHP 5.6 on windows/IISmcrypt 在 Windows/IIS 上的 PHP 5.6 中不起作用
【发布时间】:2015-12-03 13:21:27
【问题描述】:

多年来,我一直在我的 php 应用程序中大量使用 mcrypt,无论是在 win/IIS 上还是在 linux 上。虽然我在我的 linux 服务器上运行 PHP 5.4.28,但我刚刚在我的 windows 8.1 IIS 机器上升级到 PHP 5.6.11。并且 mcrypt 不再有效。它不会抛出任何我能看到的错误;它只是行不通。这是我的加密功能:

function Encrypt($text){ 
    global $salt;
    if($text != "")
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));  
    else
        return "";
}   

这在我的 linux 服务器上运行良好,但在我的本地 windows 框中返回空白。根据我的阅读,mcrypt 内置于 windows 的 php 5.6 中,因此不应该摆弄扩展名或 ini 文件。

我错过了什么?

【问题讨论】:

  • mcrypt 不使用/dev/urandom
  • 在 Windows 8 上使用 PHP 5.6.12 测试,它可以工作......它不能像你的 $text 是空的那么简单吗?试过var_dump($text)
  • 我希望你意识到Encrypt 函数是多么不安全。
  • 请注意,通过将所有调用链接在一起,您失去了调试能力,无法找到错误发生的位置。它也更难重新阅读和理解。您还将各种操作混为一谈。考虑使用具有短期变量的多个语句。编写前端开发人员阅读、理解和调试。

标签: php iis encryption mcrypt encryption-symmetric


【解决方案1】:

让我们逐段查看您的代码。 (主要是外观/空白更改。)

function Encrypt($text)
{
    global $salt; // Why not make this a second parameter?
    if($text != "") { // An unusual check, for sure
        return trim( // base64_encode doesn't leave whitespace
            base64_encode(
                mcrypt_encrypt(
                    MCRYPT_RIJNDAEL_256, // This is a non-standard variant of the
                                         // Rijndael cipher. You want to use the
                                         // MCRYPT_RIJNDAEL_128 constant if you
                                         // wanted to use AES here.
                    $salt, // This is a key, not a salt!
                    $text,
                    MCRYPT_MODE_ECB, // ECB mode is the worst mode to use for
                                     // cryptography. Among other reasons, it
                                     // doesn't even use the IV. Search for 
                                     // ECB penguins for an idea of why ECB
                                     // mode is such a bad idea.
                    mcrypt_create_iv(
                        mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB),
                        MCRYPT_RAND // You're using ECB mode so this is a waste
                                    // anyway, but you should use
                                    // MCRYPT_DEV_URANDOM instead of MCRYPT_RAND
                    )
                )
            )
        );  
    }
    return "";
}

我强烈建议您不要将此功能用于任何事情。它不安全。 Don't use ECB mode.

此外,unauthenticated encryption is dangerouslibmcrypt is abandonware

【讨论】:

  • Scott,如果你能根据你的所有建议给我一个工作示例,我会奖励你,以防你关心。
  • 是的,这很简单。使用defuse/php-encryption 而不是自己编写。
  • 嗯...使用包含在 w/php 中的 encr 库并不是我自己编写的。此外,我的 webapp 不是银行或国家安全...只是体育裁判检查他们的日程安排。
  • 您不是在编写自己的原语,而是在编写自己的协议,这同样危险。 cryptofails.com/post/75204435608/…
  • 我自己写过一次加密算法。它是基于 ASCII 替换的,所以很原始,很俗气。然而没有人能破解它。几位经验丰富的加密专家尝试过。我把它放在加密论坛上。即使在我提供了加密示例及其解密的纯文本之后,也没有人可以触摸它。这种关于“危险”加密方法、容易被黑客入侵等的说法都是无稽之谈——除非是像美国国家安全局这样的人在做黑客攻击。
【解决方案2】:

PHP 5.6 的加密要求比 5.4 更强。在 5.6 中,您会收到此警告,这确实是一个错误,因为它实际上会导致加密和解密失败:

警告:mcrypt_encrypt():此算法不支持大小为 xx 的密钥。仅支持大小为 16、24 或 32 的键。

...其中“xx”是盐值的长度。所以盐值的长度必须正好是 16、24 或 32 个字符。

【讨论】:

    【解决方案3】:

    我没有答案,但是评论太长了。

    它不会抛出任何我可以看到的错误

    您是否测试过您的配置以确认您能在错误发生时看到错误?

    但在我的本地窗口框中返回空白

    如果它正在返回,那么它不会导致致命错误。因此定义了 mcrypt 函数。您是否检查过常量是否已定义?您检查过 libmcrypt 的版本是否符合 PHP 扩展要求?

    您是否检查过 mcrypt_*() 函数的输入是否合理?

    return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))));  
    

    即使上述方法有效,它也是一段可怕的代码。编写代码和使用高级语言的原因不是你的计算机可以理解它们,而是人类可以理解代码:

    $iv=mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $encypted=mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $text, MCRYPT_MODE_ECB
                   , $iv, MCRYPT_RAND); 
    $encoded=base64_encode($encrypted);
    return $encoded;
    

    (像这样布局你的代码也可以更简单地注入检查、断点和其他调试措施)。

    【讨论】:

    • “编写代码和使用高级语言的原因不是你的计算机可以理解它们,而是人类可以理解代码”== 今日引述。
    【解决方案4】:

    正如 SweatCoder 之前所说,您的 MCRYPT_RIJNDAEL_256 密钥的长度必须为 32。要继续使用小于 32 的旧密钥(此处称为 $oldkey),请使用

    $key = str_pad($oldkey, 32, chr(0));
    

    ($key 就是你所说的 $salt)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2012-08-24
      • 2018-01-15
      • 2020-08-07
      • 2014-06-06
      • 1970-01-01
      相关资源
      最近更新 更多