0

I have code to decryp in C# and I try to porting it to PHP, here what I have done:

in C#

byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8); 
AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                cs.Close();
}
decryptedBytes = ms.ToArray();

in PHP

$saltBytes = array(1,2,3,4,5,6,7,8);
$saltBytesstring = "";
for($i=0;$i<count($saltBytes);$i++){ echo $i;
    $saltBytesstring=$saltBytesstring+chr($saltBytes[$i]);
}

$key = hash_pbkdf2("sha1", $passwordBytesstring, $saltBytesstring, 1000, 32, true); 
$arr1 = str_split($key);
for($i=0;$i<count($arr1);$i++){
    $arr1[$i] = ord($arr1[$i]);
}
echo "\nKey:"; print_r($arr1);   

Result: $key in php is not equal AES.Key C#

in PHP: Array ( [0] => 192 [1] => 203 [2] => 6 [3] ...... and so on in C#: [0]134 [1]7 [2]145 [3]54 [4]49 ....... and so on

do somethening wrong with my code?

$IV = hash_pbkdf2("sha1", $passwordBytesstring, $saltBytesstring, 1000,16,true); 
$arr2 = str_split($IV);
for($i=0;$i<count($arr2);$i++){
$arr2[$i] = ord($arr2[$i]);
}
echo "\nIV:"; print_r($arr2); 

Result: $IV in php is not equal key in C#, why?

$decrypted = mcrypt_decrypt
  (
      MCRYPT_RIJNDAEL_256,
      $key,
      $bytesToBeDecryptedbinstring,
      MCRYPT_MODE_CBC,
      $IV
   );

echo "decryp:".$decrypted;     
?>

I hope somebody give my sulution for this

  • You have a lot of unnecessary code. This wall of code is likely too large so that users don't have the time to read it all and help you. It seems to me, you currently only have a problem with implementing `Rfc2898DeriveBytes` in PHP. Can you stick to that? If this issue is solved, you can ask further questions. Please [edit] your question to reduce the scope. – Artjom B. Mar 23 '17 at 20:25
  • Thank you Artjom B, I have simplified my question just moment. – مُهَنْدِس Mar 25 '17 at 01:10
  • It seems to me like you've got PBKDF2 working in PHP and C# judging by the comments in your [other question](http://stackoverflow.com/questions/43011612/porting-c-sharp-rfc2898derivebytes-in-php-using-hash-pbkdf2). – Artjom B. Mar 25 '17 at 09:10
  • C# defaults to AES-256, but your PHP code uses Rijndael-256 for some reason. AES is a subset of Rijndael and it is equivalent to Rijndael-128. The 256 in AES-256 means the key size whereas the 256 in Rijndael-256 means the block size. AES has a fixed block size of 128 bit. Also, don't forget that you need to get 48 bytes from PBKDF2 for key *and* IV, and you need to use the same padding/unpadding as C# uses ([PKCS#7 padding](http://stackoverflow.com/a/27590539/1816580)). – Artjom B. Mar 25 '17 at 09:15
  • yes Artjom B., I simplify the case, then I've got solution from [link] (http://stackoverflow.com/questions/43011612/porting-c-sharp-rfc2898derivebytes-in-php-using-hash-pbkdf2) – مُهَنْدِس Mar 25 '17 at 13:00
  • there're 3 mistakes in my question code 1. `$saltBytesstring=$saltBytesstring+chr($saltBytes[$i]);` should be `$saltBytesstring=$saltBytesstring.chr($saltBytes[$i]);` 2. ` $key = hash_pbkdf2("sha1", $passwordBytesstring, $saltBytesstring, 1000, 32, true);` should be ` $key = hash_pbkdf2("sha1", $passwordBytesstring, $saltBytesstring, 1000, 32+16, true); ` and I didn't have to hash_pbkdf twice. Its has fixed. 3. `MCRYPT_RIJNDAEL_256` should be `MCRYPT_RIJNDAEL_128`. Thanks a lot – مُهَنْدِس Mar 25 '17 at 13:04
  • You can post your own answer. If you don't then this question will be automatically deleted after some time because it has a negative score and no answers. – Artjom B. Mar 26 '17 at 08:45

1 Answers1

1

in C#

byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);  // ---> 256 / 8 = 32
AES.IV = key.GetBytes(AES.BlockSize / 8); // ---> 128 / 8 = 16
AES.Mode = CipherMode.CBC;

using (var cs = new CryptoStream(ms, AES.CreateDecryptor(),    CryptoStreamMode.Write))
{
    cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
            cs.Close();
}
decryptedBytes = ms.ToArray();

in php

$decryptedBytes = NULL;
$saltBytes = array(1,2,3,4,5,6,7,8);
$saltBytesstring = "";
for($i=0;$i<count($saltBytes);$i++){ echo $i;
    $saltBytesstring=$saltBytesstring.chr($saltBytes[$i]);
}

$AESKeyLength = 265/8;
$AESIVLength = 128/8;

$key = hash_pbkdf2("sha1", $passwordBytesstring, $saltBytesstring, 1000, $AESKeyLength + $AESIVLength, true); 

$aeskey = (  substr($key,0,$AESKeyLength) );
$aesiv =  (  substr($key,$AESKeyLength,$AESIVLength) );

$decrypted = mcrypt_decrypt
      (
          MCRYPT_RIJNDAEL_128,
          $aeskey,
          $bytesToBeDecryptedbinstring,
          MCRYPT_MODE_CBC,
          $aesiv
       );
$arr = str_split($decrypted);
for($i=0;$i<count($arr);$i++){
    $arr[$i] = ord($arr[$i]);
}
$decryptedBytes = $arr;