AES-RIJNDAEL-256在PHP中略有差异

时间:2018-01-11 00:24:17

标签: c# php encryption aes encryption-symmetric

我能够在php中使用AES-RIJNDAEL-256加密中的CBC方法进行加密,但是当我测试代码时,我只在一个字母中略有不同,我无法理解究竟是从哪里来的,这是php代码,图像显示了不同的字符

<?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#代码:

    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

1 个答案:

答案 0 :(得分:1)

看起来一个终端能够打印出所提到的Unicode字符,而另一个终端不能;它用一个通常用于未知Unicode字符的正方形替换它。

二进制输出可能完全相同。不是直接打印出值,而是应该使用二进制比较方法比较它们,或者用十六进制或基数64打印它们。