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


Warning: mcrypt_encrypt(): key of size 10 not supported by this algorithm. only key of size 16, 24 or 32 supported

我正在尝试使用mcrypt_encrypt()加密密码。它在localhost上运行良好,但当它联机时,我的输出是"",我收到了以下警告:

警告:mcrypt_encrypt():不支持大小为10的密钥这个算法。只有尺寸为16、24或32的钥匙才支持

这是我正在使用的代码:

$text="thisismypassword123";
$salt="1234567824";
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
            )
        )
    )
);

造成这种情况的原因是什么?我能做些什么来解决这个问题?

解决向后兼容性的简单方法是用''0填充当前密码。

例如,对于您当前在PHP 5.4上的$key="1234567890",由于当前密钥大小为10,它将停止在PHP 5.6版本上工作。

要在不影响应用程序的情况下解决此问题,只需更改为$key="1234567890''0''0''0''0''0"(直到达到1632,…)

我正在尝试加密密码

这可能是个错误。事实上,你把钥匙称为"盐",这让我更加警惕。需要存储用户的密码吗加密不是适合该作业的工具密码散列是。它们是截然不同的概念。

但是,让我们忽略"错误的作业工具"方面,并假设您出于某种原因加密了非密码字符串。即使在这种情况下,您的加密代码也是不安全的。

return trim ( // Why are you trimming this?
    base64_encode (
        mcrypt_encrypt (
            MCRYPT_RIJNDAEL_256, // Not AES
            $salt,
            $text,
            MCRYPT_MODE_ECB,     // The WORST mode possible
            mcrypt_create_iv (   // ECB mode doesn't use an IV
                mcrypt_get_iv_size (
                    MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB
                ),
                MCRYPT_RAND      // Even if an IV was used, MCRYPT_RAND
                                 // is a bad choice! Use MCRYPT_DEV_URANDOM
            )
        )
    )
);

即使你解决了上面的问题,你还有一个更严重的问题:选择密文攻击。

解决方案:

  • 对于密码,请使用密码哈希API
  • 对于通用数据加密,请使用提供经过身份验证的加密的密码库

你能告诉给你代码片段的人他们在互联网上传播不安全的代码吗?谢谢

警告有什么不清楚的地方?提供尺寸可接受的钥匙。

密钥就是你所说的$salt,它不是salt,而是加密密钥。重命名它以使代码更加清晰。

一些实例可能会向密钥添加填充字节,但这是非标准的,并且对于不同的实现可能会有所不同。不要信任参数填充,请指定完整的长度。

同样来自加密文档:

MCRYPT_RIJNDAEL_256不是AES-256,它是RIJNDAEL分组密码的不同变体。如果要在mcrypt中使用AES-256,则必须使用带有32字节密钥的mcrypt_RIJNDAEL_128。

您应该使用AES选项。

该代码使用ECB模式,该模式不安全,不应使用,也不使用IV。可能你想做的是使用CBC模式,它确实需要IV。解密需要相同的IV。

应该不需要trim Base64编码。

最后,嵌套几个级别的函数(此处为6)似乎是个好主意,但由于中间结果无法检查,因此调试几乎是不可能的。

然后是mcrypt,最好不要使用mcrypt,它是废弃软件,多年没有更新,不支持标准的PKCS#7填充,只有非标准的null填充,甚至不能与二进制数据一起使用。相反,可以考虑使用缓和措施,因为它正在得到维护,而且是正确的。

在PHP 5.6及更高版本中,$salt需要是一个长度为16、24或32个字符的随机字符串。您的localhost可能仍然使用旧版本的PHP。

这段代码应该在本地主机和服务器上都能工作:

$text="thisismypassword123";
$salt="ddv21sd5dv56sd51"; // <- 16 characters long
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
            )
        )
    )
);

备注

尽管此代码确实有效,但您可能还需要考虑其他问题。

请参阅其他答案(尤其是Scott Arciszewski的答案),了解代码中还有什么问题,以及为什么您根本不应该使用mcrypt_encrypt()的详细信息