Page 1 of 1

PHP / Mcrypt problem

Posted: Wed Oct 26, 2005 7:24 pm
by Neron
Hi all together,

I have PHP 4.4 with Mcrypt support installed and I'm creating a crossplatform application which has to crypt and decrypt on different hosts. So I got the problem that if I crypt on the developer host PHP 5.x and decrypt on the PHP 4.4 host the result is not a plain text, it's just a scrambled text (decryption does not work the same). Does anyone had such a problem or does anybody has a solution beside upgrading to PHP 5.x ?

If I have to upgrade then I will loose all potential customers which run PHP 4.x...

I think it's not a padding problem (to solve with trim()) because it's ocurring allways on one machine...
I think it must be something with incompatibility between different versions of php or mcrypt...

Sorry about my English, but I can read manuals better than writing them

Thank's for your help !

Posted: Wed Oct 26, 2005 7:27 pm
by feyd
post code, please.

Sorry, here is the code...

Posted: Fri Oct 28, 2005 12:52 pm
by Neron
Hi here I post the code. It took some time because I don't have an Internet Connection at home...
The two functions encrypt and decrypt

Code: Select all

function encrypt_data($key_chars, $data) {


  // ==============================================================
  // Specify the encryption settings.
  // ==============================================================
  $algorithm  = MCRYPT_BLOWFISH;
  $mode = MCRYPT_MODE_CBC;


  // ==============================================================
  // Open the cipher module.
  // ==============================================================
  $td = mcrypt_module_open($algorithm, '', $mode, '');


  // ==============================================================
  // Determine the keysize length.
  // ==============================================================
  $key_size = mcrypt_enc_get_key_size($td);


  // ==============================================================
  // Create an encryption key.
  // ==============================================================
  $key_string = md5($key_chars).md5(strrev($key_chars));
  $encryption_key = substr($key_string, 0, $key_size);


  // ==============================================================
  // Get the initialization vector size.
  // ==============================================================
  $iv_size = mcrypt_get_iv_size($algorithm, $mode);


  // ==============================================================
  // Check if the host is a windows host.
  // ==============================================================
  if (isset($_SERVER['WINDIR'])) {
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  } else {
    $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
  }


  // ==============================================================
  // Encrypt the data.
  // ==============================================================
  $encrypted_data = mcrypt_encrypt($algorithm, $encryption_key, $data, $mode, $iv);


  // ==============================================================
  // Close the cipher module.
  // ==============================================================
  mcrypt_module_close($td);


  // ==============================================================
  // Encode the data to base64.
  // ==============================================================
  $crypt_array['data'] = base64_encode($encrypted_data);


  // ==============================================================
  // Store the initialization vector in the encrypt array.
  // ==============================================================
  $crypt_array['iv'] = base64_encode($iv);


  // ==============================================================
  // Return the encrypted data to the caller.
  // ==============================================================
  return $crypt_array;
}


function decrypt_data($key_chars, $data, $iv) {


  // ==============================================================
  // Specify the encryption settings.
  // ==============================================================
  $algorithm  = MCRYPT_BLOWFISH;
  $mode = MCRYPT_MODE_CBC;


  // ==============================================================
  // Open the cipher module.
  // ==============================================================
  $td = mcrypt_module_open($algorithm, '', $mode, '');


  // ==============================================================
  // Get the initialization vector size.
  // ==============================================================
  $iv_size = mcrypt_get_iv_size($algorithm, $mode);


  // ==============================================================
  // Decode the iv from base64.
  // ==============================================================
  $iv = base64_decode($iv);


  // ==============================================================
  // Check the initialization vector size.
  // ==============================================================
  if (strlen($iv) == $iv_size) {


    // ============================================================
    // Determine the keysize length.
    // ============================================================
    $key_size = mcrypt_enc_get_key_size($td);


    // ============================================================
    // Create an encryption key.
    // ============================================================
    $key_string = md5($key_chars).md5(strrev($key_chars));
    $encryption_key = substr($key_string, 0, $key_size);


    // ============================================================
    // Decode the data from base64.
    // ============================================================
    $data = base64_decode($data);


    // ============================================================
    // Decrypt the data.
    // ============================================================
    $decoded_data = mcrypt_decrypt($algorithm, $encryption_key, $data, $mode, $iv);
  } else {


    // ============================================================
    // The initialization vector size does not match.
    // ============================================================
    $decoded_data = "fail";
  }


  // ==============================================================
  // Return the decrypted data to the caller.
  // ==============================================================
  return $decoded_data;
}
Thank's a lot and have a nice day !

Posted: Sun Oct 30, 2005 7:40 am
by yum-jelly
Your missing your seed call srand();


This...

Code: Select all

if (isset($_SERVER['WINDIR'])) { 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
  } else { 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM); 
  }

Should be...

Code: Select all

if ( isset ( $_SERVER['WINDIR'] ) )
{
	srand ( ( double ) microtime () * 1000000 ); // or just, srand(); without the param would also work!

	$iv = mcrypt_create_iv ( $iv_size, MCRYPT_RAND );
}
else
{
	$iv = mcrypt_create_iv ( $iv_size, MCRYPT_DEV_URANDOM );
}

yj

Thank's !

Posted: Sun Oct 30, 2005 1:52 pm
by Neron
Hi !

Thank's for your reply ! That could be the problem because I have read the following on php.net:
Note: As of PHP 4.2.0, there is no need to seed the random number generator with srand() or mt_srand() as this is now done automatically.
So if I use it on a system below php 4.2.0 it will not work without srand() ...

Thank's a lot and have a nice day !

Posted: Tue Nov 01, 2005 6:05 am
by Maugrim_The_Reaper
Your missing your seed call srand();
It's still valid even in later versions than 4.2.0, but yep not a requirement I think since that version. Unless mcrypt has special needs?