у меня есть мой старый код еще с 2011 года, который вычисляет хэш
private static $key = '[email protected]#€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.
Или, альтернативно, есть ли способ, как сломать хеш, если я все еще получил функцию?
с этим я могу потенциально начать использовать новый способ вычисления хэша.
Спасибо за любой совет
Если вы обратитесь к журналу изменений в документация для mcrypt_encrypt
, Вы должны увидеть, что начиная с PHP 5.6.0 …
Недействительным
key
а такжеiv
размеры больше не принимаются.mcrypt_encrypt()
Теперь выкину предупреждение и вернусьFALSE
если входные данные неверны. Ранее ключи и капельницы были дополнены'\0'
байт до следующего допустимого размера.
Поэтому решение состоит в том, чтобы заменить ваш ключ на тот, который дополняется нулевыми символами до 32 байтов.
К сожалению, там есть не-ASCII-символ (знак евро), поэтому существует множество возможностей его кодирования. Вероятно, лучше всего вручную закодировать этот символ. В Юникоде знак евро имеет кодовую точку U + 20AC, которая будет переводиться в ‘\ xE2 \ x82 \ xAC’ (что объясняет, почему mcrypt считает 29 байтов вместо 27), что делает ваш новый ключ
private static $key = '[email protected]#\xE2\x82\xAC2011GAMESITES\0\0\0';
Обратите внимание, что мы должны принять некоторую кодировку символов для вашего кода; Я принял UTF-8. Маловероятно, но возможно, что в 2011 году он должен был быть закодирован в другой кодировке символов (например, ISO-8859-1), что привело к совершенно другому кодированию знака евро.
$key
является ключом и должен иметь поддерживаемый размер 16, 24 или 32 байта в длину. Вы передаете длину 29 байт, вам нужно использовать ключ соответствующего размера.
Код не вычисляет хеш, он шифрует $text
,
Он использует режим ECB, который не считается безопасным. Обратите внимание, что режим ЕЦБ не берет iv $iv
так что нет смысла его создавать. Режим CBC лучше и использует iv.
Если вы действительно хотите создать хеш, используйте хеш-функцию, такую как SHA-256. Если вам нужен хеш с ключами или солями, используйте HMAC.
Даже шифрование «назад в 2011» не использовалось для создания хэшей, с тех пор на самом деле ничего нового не было.
Выполните итерацию по HMAC со случайной солью в течение примерно 100 мс (соль должна быть сохранена с помощью хэша). Используйте такие функции, как password_hash, PBKDF2, Bcrypt и аналогичные функции. Смысл в том, чтобы заставить злоумышленника тратить много времени на поиск паролей грубой силой.
См. OWASP (Открытый проект безопасности веб-приложений) Шпаргалка для хранения пароля.
Увидеть Как надежно хешировать пароли, Теория на бирже безопасности