我正在尝试使用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"(直到达到16或32,…)
我正在尝试加密密码
这可能是个错误。事实上,你把钥匙称为"盐",这让我更加警惕。需要存储用户的密码吗加密不是适合该作业的工具密码散列是。它们是截然不同的概念。
但是,让我们忽略"错误的作业工具"方面,并假设您出于某种原因加密了非密码字符串。即使在这种情况下,您的加密代码也是不安全的。
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()
的详细信息