i have my old code back from 2011 which calculate hash
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);
}
When i try to run it now I get an error:
Warning: mcrypt_encrypt(): Key of size 29 not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported in ..\Hash.php on line 27
I know it takes a long time from 2011 and there can be better ways to do it now, but I need to make it work from previous version for some historical issue. What i am doing wrong? I cant even see what size 29 does it mean.
Or alternativly is there a way how to break a hash if I still got a function? with this i can potencialy start using new way of calculating hash.
Thanks for any advise
If you consult the changelog in the documentation for mcrypt_encrypt
, you should see that since PHP 5.6.0...
Invalid
key
andiv
sizes are no longer accepted.mcrypt_encrypt()
will now throw a warning and returnFALSE
if the inputs are invalid. Previously keys and IVs were padded with'\0'
bytes to the next valid size.
The solution is therefore to replace your key by one that is padded with null characters to 32 bytes.
Unfortunately, there is a non-ASCII character in there (the euro sign), so there are multiple possibilities how that is supposed to be encoded. It's probably best to manually encode this character. In Unicode, the euro sign has codepoint U+20AC, which would translate to '\xE2\x82\xAC' (which explains why mcrypt counts 29 bytes instead of 27), making your new key
private static $key = 'G@W351T35.cz#\xE2\x82\xAC2011GAMESITES\0\0\0';
Note that we have to assume some character encoding for your code; I have assumed UTF-8. It's unlikely but possible that, in 2011, it was supposed to be encoded in another character encoding (e.g. ISO-8859-1), which results in a very different encoding for the euro sign.
$key
is the key and must be a supported size of 16, 24 or 32 bytes in length. You are passing a length of 29 bytes, you need to use a key of appropriate size.
The code is not calculating a hash, it is encrypting $text
.
It is using ECB mode which is not considered secure. Note that ECB mode does not take an iv $iv
so there is no point in creating one. CBC mode is better and does use an iv.
If you really want to create a hash use a hash function such as SHA-256. If you need a "keyed" or salted hash use a HMAC.
Even "way back to 2011" encryption was not used to create hashes, there really isn't anything new since then.
Iterate over an HMAC with a random salt for about a 100ms duration (the salt needs to be saved with the hash). Use functions such as password_hash, PBKDF2, Bcrypt and similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force.
See OWASP (Open Web Application Security Project) Password Storage Cheat Sheet.
See How to securely hash passwords, The Theory on Security Stackexchange.