-3

I was to able to have a function in php which encrypts via CBC method in AES-RIJNDAEL-256 encryption , but when I tested the code I got a slight difference only in one letter which I can not understand where exactly came from , here is the php code and the image shows what is the different character

<?php

$string_0 = "msDoss";
$string_1 = "sALtValue";
$string_3 = "~1B2c3D4e5F6g7H8";

function PBKDF1($pass, $salt, $count, $cb)
{
  // This is very approximately the way that the Microsoft version of 
  // PasswordDeriveBytes works.

  ///
  /// !!!WARNING!!!
  ///
  // This is a BAD function!
  // Irrespective of the fact that the use of PBKDF1 is not recommended anyway.
  //
  // This really should be put into a class with a constructor taking the 
  // $pass, $salt and $count.
  // Then there should be a Reset() method to start from scratch each time a new pwd/salt is used.
  // And there should be a GetBytes(int) method to get the required info.
  // But for the sake of simplicity we are assuming the same pwd and salt for each call to 
  // this function. This will not stand up to any scrutiny!

  static $base;
  static $extra;
  static $extracount= 0;
  static $hashno;
  static $state = 0;

  if ($state == 0)
  {
    $hashno = 0;
    $state = 1;

    $key = $pass . $salt;
    $base = sha1($key, true);
    for($i = 2; $i < $count; $i++)
    {
      $base = sha1($base, true);
    }
  }

  $result = "";

  // Check if we have any bytes left over from a previous iteration.
  // This is the way MS appears to do it. To me it looks very badly wrong
  // in the line: "$result = substr($extra, $rlen, $rlen);"
  // I'm sure it should be more like "$result = substr($extra, $extracount, $rlen);"
  // Mono have provided what looks like a fixed version at
  // https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs
  // But I'm no cryptographer so I might be wrong.
  // But this seems to work for low values of $hashno and seems to work
  // with C# implementations.

  if ($extracount > 0)
  {
    $rlen = strlen($extra) - $extracount;
    if ($rlen >= $cb)
    {
      $result = substr($extra, $extracount, $cb);
      if ($rlen > $cb)
      {
        $extracount += $cb;
      }
      else
      {
        $extra = null;
        $extracount = 0;
      }
      return $result;
    }
    $result = substr($extra, $rlen, $rlen);
  }

  $current = "";
  $clen = 0;
  $remain = $cb - strlen($result);
  while ($remain > $clen)
  {
    if ($hashno == 0)
    {
      $current = sha1($base, true);
    }
    else if ($hashno < 1000)
    {
      $n = sprintf("%d", $hashno);
      $tmp = $n . $base;
      $current .= sha1($tmp, true);
    }
    $hashno++;
    $clen = strlen($current);     
  }

  // $current now holds at least as many bytes as we need
  $result .= substr($current, 0, $remain);

  // Save any left over bytes for any future requests
  if ($clen > $remain)
  {
    $extra = $current;
    $extracount = $remain;
  }

  return $result; 
}
$encryption_key= PBKDF1($string_0, $string_1, 7, 32);
?>

C# Code :

    byte[] bytes = Encoding.ASCII.GetBytes(Class27.string_3);
    byte[] bytes2 = Encoding.ASCII.GetBytes(Class27.string_1);
    byte[] array = Convert.FromBase64String(string_4);
    byte[] bytes3 = new PasswordDeriveBytes(Class27.string_0, bytes2, Class27.string_2, 7).GetBytes(32);
    ICryptoTransform transform = new RijndaelManaged
    {
        Mode = CipherMode.CBC
    }.CreateDecryptor(bytes3, bytes);

Difference

Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • 1
    I am confused. Your function doesn't have any relation to AES (or Rijndael) at all. –  Jan 11 '18 at 00:26
  • This is the function used to create the encryption key through PBKDF1 method which is equivalent to PasswordDeriveBytes in C# . I am adding the code which decrypts now in the main post – ESAM GALAL Jan 11 '18 at 00:44
  • you should post the error lines as text and not an image of it. – Funk Forty Niner Jan 11 '18 at 00:51
  • it is not error lines , code word perfect but gives different value in one char which shown in image . function is posted here [link](https://www.experts-exchange.com/questions/28514171/Can't-decrypt-AES-RIJNDAEL-256-In-PHP.html) – ESAM GALAL Jan 11 '18 at 00:56
  • Provide a [mcve], the would include test data demonstrating the error. – zaph Jan 11 '18 at 02:14
  • 1
    1. Output them as hex for *meaningful* comparison and possible insight. 2. Copy/paste, not screenshots. – Sammitch Jan 11 '18 at 02:25
  • 1
    Also are you talking about the output from your key derivation function [aka PBKDF1] or the actual encryption? It's not clear from either the code or your description what your example output represents. – Sammitch Jan 11 '18 at 02:30
  • @Sammitch I am taking about the output which comes form the values mentioned on the first php example , The code with show the second input and C# will give the first one – ESAM GALAL Jan 12 '18 at 19:10

1 Answers1

1

It looks like one terminal is able to print out the Unicode character that is mentioned and the other doesn't; it replaces it by a square which is usually used for unknown Unicode characters.

It's likely that the binary output is exactly the same. Instead of printing out the values directly you should be comparing them using a binary compare method or by printing them out in hexadecimals or base 64.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • when I used the hex for output I also got a different value that's why I was confused , neither binary nor hex gave the same result just the same different character – ESAM GALAL Jan 12 '18 at 19:09