Php mcrypt_encrypt():此算法不支持大小为29的密钥

Php mcrypt_encrypt():此算法不支持大小为29的密钥,php,mcrypt,rijndael,Php,Mcrypt,Rijndael,我有我的旧代码从2011年开始计算散列 private static $key = 'G@W351T35.cz#€2011GAMESITES'; /** * Computes salted password hash. * @param string * @return string */ public static function calculateHash($password) { $text = $password; $iv_size = mcrypt_get

我有我的旧代码从2011年开始计算散列

private static $key = 'G@W351T35.cz#€2011GAMESITES';

/**
 * Computes salted password hash.
 * @param  string
 * @return string
 */
public static function calculateHash($password)
{
    $text = $password;
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::$key, $text, MCRYPT_MODE_ECB, $iv);
    return base64_encode($crypttext);
}
当我现在尝试运行它时,我得到一个错误:

警告:mcrypt_encrypt():此服务器不支持大小为29的密钥 算法。..\Hash.php仅支持大小为16、24或32的键 第27行

我知道从2011年开始需要很长时间,现在可以有更好的方法来完成,但我需要让它在一些历史问题的前一个版本中工作。我做错了什么? 我甚至看不出29码是什么意思

或者,如果我还有一个函数,有没有办法打破散列? 有了这个,我就可以开始使用新的散列计算方法了


感谢您的建议

是密钥,并且必须是支持的长度为16、24或32字节的大小。如果传递的长度为29字节,则需要使用适当大小的密钥

代码不是在计算散列,而是在加密
$text

它使用的是ECB模式,这被认为是不安全的。请注意,ECB模式不采用iv
$iv
,因此没有必要创建一个。CBC模式更好,并且使用静脉注射

如果您真的想创建散列,请使用散列函数,如SHA-256。如果您需要一个“键控”或盐渍哈希,请使用HMAC

即使是“回到2011年”的加密也没有被用来创建散列,从那以后真的没有什么新东西了

使用随机salt在HMAC上迭代大约100ms(salt需要与散列一起保存)。使用诸如password_hash、PBKDF2、Bcrypt等函数和类似函数。关键是让攻击者花费大量时间通过暴力手段查找密码

请参阅OWASP(开放式Web应用程序安全项目)


请参阅Security Stackexchange。

如果您在中查阅变更日志,您应该会看到,由于PHP5.6.0

无效的
iv
尺寸不再被接受
mcrypt_encrypt()
现在将抛出警告,如果输入无效,则返回
FALSE
。以前,键和IVs用
'\0'
字节填充到下一个有效大小

因此,解决方案是将您的密钥替换为一个由空字符填充到32字节的密钥

不幸的是,里面有一个非ASCII字符(欧元符号),因此有多种可能是如何编码的。最好是手动编码这个字符。在Unicode中,欧元符号具有代码点U+20AC,这将转换为“\xE2\x82\xAC”(这解释了为什么mcrypt计数为29字节而不是27字节),从而生成新密钥

private static $key = 'G@W351T35.cz#\xE2\x82\xAC2011GAMESITES\0\0\0';

请注意,我们必须为您的代码假设一些字符编码;我假设是UTF-8。不太可能,但也有可能,在2011年,它应该用另一种字符编码(例如ISO-8859-1)进行编码,这会导致欧元符号的编码方式完全不同。

请参阅中的答案。至于将来实现密码哈希:不要自己发明,而是使用现有的、经过充分研究的密码哈希。一个很好的例子是
bcrypt
,它是通过PHP的和支持的G@W351T35.cz#欧元2011GAMESITES'是27个字符,不是29个字符,那么有没有办法从散列中获得一个真正的密码呢?要在没有任何用户交互的情况下强制进行更改,您确实需要返回到问题,如果您想要一个好的答案和安全的代码,请添加您试图完成的内容。