我正在尝试使用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 :(得分:4)
我正在尝试加密密码
This is probably a mistake。你把钥匙称为“盐”的事实让我更加警惕。需要存储用户密码? 加密是 NOT 正确的工作工具。 密码哈希是。 They're wildly different concepts
但是,让我们忽略“工作的错误工具”方面,并假设您出于某种原因加密了非密码字符串。即使在这种情况下,您的加密代码也是不安全的。
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 ) ) ) );
即使您修复了上述问题,您也会遇到更严重的问题:Chosen-ciphertext attacks。
解决方案:
你能告诉那些曾经给你的代码片段他们在互联网上传播不安全的代码吗?感谢。
答案 1 :(得分:2)
警告有什么不清楚的地方?提供可接受尺寸的钥匙。
关键是你所谓的$ salt,它不是盐,它是加密密钥。重命名它以使代码更清晰。
某些实例可能会向密钥添加填充字节,但这是非标准的,并且对于不同的实现可能会有所不同。不要信任参数填充,指定全长。
同样来自加密文档:
MCRYPT_RIJNDAEL_256不是AES-256,它是Rijndael分组密码的不同变体。如果你想在mcrypt中使用AES-256,你必须使用带有32字节密钥的MCRYPT_RIJNDAEL_128。
您应该使用AES选项。
代码使用ECB模式,该模式不安全,不应使用且不使用IV。您可能想要做的是使用需要IV的CBC模式。解密时需要相同的IV。
不需要trim
Base64编码。
最后,嵌套几个级别的函数(这里是6个)似乎是一个好主意,但由于无法检查中间结果,因此几乎不可能进行调试。
然后有mcrypt
,最好不要使用mcrypt,它是abandonware,多年没有更新,不支持标准的PKCS#7填充,只有非标准的空填充,不能甚至可以用于二进制数据。而是考虑使用defuse,它正在被维护并且是正确的。
答案 2 :(得分:2)
解决后向兼容性的简单方法是用\ 0。
填充当前密码例如,对于PHP 5.4上的当前$ key =“1234567890”,由于当前密钥大小为10,它将停止在PHP 5.6版本上运行。
要解决它而不影响应用程序只需更改为$ key =“1234567890 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0”(直到 16 或 32 强>,...)
答案 3 :(得分:-1)
在PHP 5.6及更高版本中,您的$salt
需要是一个随机字符串,长度为16,24或32个字符。您的localhost可能仍然使用旧版本的PHP。
此代码应在localhost和服务器上运行:
$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()
到位!