mcrypt 在 PHP 5.6 on windows/IIS 中不起作用

mcrypt doesn't work in PHP 5.6 on windows/IIS

多年来,我一直在我的 php 应用程序中大量使用 mcrypt,在 win/IIS 和 linux 上都是如此。尽管我的 运行 PHP 5.4.28 在我的 linux 服务器上,但我刚刚在我的 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 框上 returns 空白。根据我的阅读,mcrypt 内置于 php 5.6 for windows,因此不应该摆弄扩展名或 ini 文件。

我错过了什么?

我没有答案,但这对于评论来说太长了。

It doesn't throw any errors that I can see

您是否测试了您的配置以验证您是否可以在错误发生时看到它们?

but returns blank on my local windows box

如果它正在返回,那么它不会导致致命错误。因此定义了 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;

(像这样布置代码还可以更轻松地注入检查、断点和其他调试措施)。

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

Warning: mcrypt_encrypt(): Key of size xx not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported.

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

让我们逐条查看您的代码。 (主要是 cosmetic/whitespace 更改。)

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 dangerous and libmcrypt is abandonware

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

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

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