【发布时间】:2018-01-11 00:24:17
【问题描述】:
我能够在 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);
【问题讨论】:
-
我很困惑。您的函数与 AES(或 Rijndael)根本没有任何关系。
-
这是通过PBKDF1方法创建加密密钥的函数,相当于C#中的PasswordDeriveBytes。我在主帖中添加现在解密的代码
-
您应该将错误行发布为文本而不是图像。
-
1.将它们输出为十六进制以进行有意义的比较和可能的洞察。 2. 复制/粘贴,而不是截图。
-
您是在谈论密钥派生函数 [aka PBKDF1] 的输出还是实际加密?从代码或您的描述中都不清楚您的示例输出代表什么。
标签: c# php encryption aes encryption-symmetric