【问题标题】:mcrypt_encrypt(): Key of size 29 not supported by this algorithmmcrypt_encrypt():此算法不支持大小为 29 的密钥
【发布时间】:2016-11-03 01:36:31
【问题描述】:

我有我从 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 是什么意思。

或者如果我仍然有一个函数,是否有办法打破哈希? 有了这个,我就可以开始使用计算哈希的新方法了。

感谢您的建议

【问题讨论】:

标签: php mcrypt rijndael


【解决方案1】:

$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。

【讨论】:

  • 我可能是错的,但 $key 是 'G@W351T35.cz#€2011GAMESITES' 是 27 个字符而不是 29 个
  • 好吧,有没有办法从哈希中获取真正的密码呢?在没有任何用户交互的情况下强制以这种方式进行更改
  • 如果你想要一个好的答案和安全的代码,你真的需要回到这个问题添加你想要完成的事情。
【解决方案2】:

如果您查阅 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),这导致欧元符号的编码非常不同。

【讨论】:

    猜你喜欢
    • 2016-07-22
    • 2016-11-25
    • 2018-07-11
    • 1970-01-01
    • 2015-03-13
    • 2015-09-16
    • 2021-12-05
    • 2011-02-24
    相关资源
    最近更新 更多