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

时间:2016-06-30 19:39:52

标签: 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_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的密钥   算法。只有大小为16,24或32的键支持在.. \ Hash.php中   在第27行

我知道从2011年开始需要很长时间,现在可以有更好的方法来实现,但我需要在以前的版本中使用它来解决一些历史问题。我做错了什么? 我甚至不知道它的大小是什么意思。

或者替代地,如果我还有一个函数,有没有办法打破哈希? 有了这个,我可以开始使用新的计算哈希方式。

感谢您的任何建议

2 个答案:

答案 0 :(得分:1)

如果您查阅the documentation for mcrypt_encrypt中的更改日志,您应该会看到自PHP 5.6.0以后...

  

不再接受 key iv 尺寸无效。如果输入无效, mcrypt_encrypt() 现在会发出警告并返回 FALSE 。之前的密钥和IV用 '\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),这导致欧元符号的编码非常不同。

答案 1 :(得分:0)

$key是密钥,必须是支持的长度为16,24或32字节的大小。您传递的是29个字节的长度,您需要使用适当大小的密钥。

代码不计算哈希值,它正在加密$text

使用的ECB模式不被认为是安全的。请注意,ECB模式不会采用iv $iv,因此创建一个没有意义。 CBC模式更好,并使用iv。

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

甚至“回到2011年的方式”加密并没有被用来创造哈希,从那以后真的没有什么新东西。

使用随机盐在HMAC上迭代大约100毫秒的持续时间(盐需要与哈希一起保存)。使用password_hash,PBKDF2,Bcrypt等功能。重点是让攻击者花费大量时间通过暴力破解密码。

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

请参阅Security Stackexchange上的How to securely hash passwords, The Theory