我收到了一个带密码的SQL服务器数据库。该数据库来自.NET网站。我正在重建网站到PHP,所以我想使用自己的加密算法的密码。为此,我尝试从源数据库解密密码,但到目前为止还没有成功。
根据原始开发者的说法,它使用Rijndael加密。密钥作为数据库中的blob字段。我导出它们并尝试使用PHP来解密密码。我没有成功,但在Stack溢出的某处读取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之类的网络工具转换它,但这并没有给我一个有效的字符串(只是一些奇怪的字符。所以我不确定这是否与它有任何关系,但如果是这样,如何转换它?
答案 0 :(得分:1)
错误在以下两行中:
var iv = Encoding.UTF8.GetBytes("5F38D2742EFC59486F6CBDDAB3E46EC5");
var key = Encoding.UTF8.GetBytes("F88640BE83A6911472BA4AF9B9C37E2C2B3E78BCFECF4BC6ADE1E928441F6AD7");
您在字符串文字中的内容似乎是十六进制字符串。这些应该通过依次取每对字符并将其转换为byte
来解码。遗憾的是,.NET框架中没有内置函数来执行此操作,但问题How do you convert Byte Array to Hexadecimal String, and vice versa, in C#应包含一些有用的提示来实现此目的。
相反,您当前的代码将依次获取每个字符,并计算一个或多个(好的,在这种情况下,总是一个)byte
值,即该字符的UTF8值。
这是两个非常不同的操作,但是字符的消耗方式不同,这就是为什么你得到的字节数比你预期的要多两倍。