So I was writing a web application and for some uses I need to encrypt string and decrypt it later, and everything from my code works perfectly on localhost on Macbook on El Capitan 10.11.4 and XAMPP 5.6.15-1 but when I upload code on the server it just wont work. I found one problem (Also I tried on multiple servers).
So this is my code:
<?php
session_start();
header("Content-Type: text/html;charset=UTF-8");
if (isset($_POST["file"])) {
$filename = $_POST["file"];
//$filename = $_GET["file"];
$filename = substr($filename, 12);
$username = $_SESSION["username"];
$key = $_SESSION["key"];
$filename = "../users/$username/text/" . $filename;
$fileNumber = $_POST["number"];
///Cloude/users/antonio/text/teext/file2.txt
// Cloude/script
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;
$decrypt = str_replace(" ", "+", $contents);
echo " ------ 1 ------ ";
$decrypt = explode('|', $decrypt.'|');
$decoded = base64_decode($decrypt[0]);
$iv = base64_decode($decrypt[1]);
echo " ------ 2 ------";
if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
echo " ------ 3 ------";
$key = pack('H*', $key);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
$mac = substr($decrypted, -64);
$decrypted = substr($decrypted, 0, -64);
$calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
if($calcmac!==$mac){ return false; }
$decrypted = unserialize($decrypted);
echo json_encode($decrypted . "qJB0rGtIn5UB1xG03efyCp55");
}
and, this echoes are just for testing which line won't work. So when I try to run it all it will just print "------ 1 ------ and ------ 2 ------", the code after
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)
just wont work on server, does anyone knows why?
EDIT: I found the bug, it was the hosting problem, they do some weird things, thanks anyway!
You should not use the MCrypt functions anymore. Why? because MCrypt is considered abandonware. The library is no longer actively maintained and a long list of known bugs are not fixed since a long time.
So, what would be the solution to your problem? The quick, easy and safest option is to use a drop in library.
Example of doing strong crypto the easy way:
// Assuming a PSR-4 compatible autoloader
use Driftwood\SymmetricEncryption;
$password = 'correct horse battery staple';
$crypto = new SymmetricEncryption(20);
$encrypted = $crypto->encrypt('Never roll your own crypto.', $password);
$decrypted = $crypto->decrypt($encrypted, $password);
echo $decrypted; // Never roll your own crypto.
If you reaally want to create your own crypto library (you shouldn't) then the recommended solution is to use PHP's OpenSSL extension.
But: crypto is hard, exceptionally hard. A good crypto wrapper requires multiple cryptographers and PHP specialists working together, checking each other and double checking each change in the code. Scrutinizing every decision.