0

我收到了一个带有密码的 SQL 服务器数据库。该数据库来自一个 .NET 网站。我正在将网站重建为 PHP,所以我想对密码使用自己的加密算法。为此,我尝试从源数据库中解密密码,但到目前为止还没有成功。

根据原始开发人员的说法,它使用 Rijndael 加密。键是数据库中的 blob 字段。我将它们导出并尝试使用 PHP 来解密密码。我没有成功,但在堆栈溢出的某个地方读到 PHP 和 .NET 实现它的方式有所不同。这只能通过更改 .NET 中的加密方式来解决,但这不是一种选择。

所以接下来我尝试创建一个小的 .NET Web 表单来解码密码。对于测试,我使用以下代码:

var iv = Encoding.UTF8.GetBytes("5F38D2742EFC59486F6CBDDAB3E46EC5");
var key = Encoding.UTF8.GetBytes("F88640BE83A6911472BA4AF9B9C37E2C2B3E78BCFECF4BC6ADE1E928441F6AD7");

var rijndael = new RijndaelManaged
{
    BlockSize = 256,
    IV = iv,
    KeySize = 256,
    Key = key
};
rijndael.Padding = PaddingMode.None;
var buffer = Convert.FromBase64String("D1jo49HH6cL4kZVVeIDyDbJGtO4+f2N9YIonOqRg6hM=");
var transform = rijndael.CreateDecryptor();
string decrypted;
using (var ms = new MemoryStream())
{
    using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write))
    {
        cs.Write(buffer, 0, buffer.Length);
        cs.FlushFinalBlock();
        decrypted = Encoding.UTF8.GetString(ms.ToArray());
        cs.Close();
    }
    ms.Close();
}
Label1.Text = decrypted;

顺便说一下,我已经更改了键,但字符数仍然相同。显然密钥的大小是 512 位而不是 256 位。但这不受 Rijndael 的支持。当我拿走一半密钥时,它不会产生任何错误,但当然不会给我正确的密码。

现在我注意到密钥是十六进制字符。我尝试使用诸如http://www.string-functions.com/hex-string.aspx之类的网络工具对其进行转换,但这并没有给我一个有效的字符串(只是一些奇怪的字符。所以我不确定是否这与它有什么关系,但如果是这样,如何转换它?

4

1 回答 1

1

错误在这两行:

var iv = Encoding.UTF8.GetBytes("5F38D2742EFC59486F6CBDDAB3E46EC5");
var key = Encoding.UTF8.GetBytes("F88640BE83A6911472BA4AF9B9C37E2C2B3E78BCFECF4BC6ADE1E928441F6AD7");

您的字符串文字中的内容似乎是十六进制字符串。这些应该通过依次获取每对字符并将它们转换为byte. 不幸的是,.NET 框架中没有内置函数来执行此操作,但是问题如何将字节数组转换为十六进制字符串,反之亦然,在 C# 中应该包含一些有用的提示来实现这一点。

相反,您当前的代码将依次获取每个字符,并计算一个或多个(好吧,在这种情况下,始终是一个)byte值,即该字符的 UTF8 值。

这是两个非常不同的操作,但是字符是/应该如何被消耗的差异是为什么你得到的字节数是你期望接收的字节数的两倍。

于 2012-08-24T06:24:09.057 回答