我继承了一些最初在.NET 4.6中构建的遗留代码,如下所示:
static void Main(string[] args)
{
Console.WriteLine(Encrypt("B9519163"));
}
public static string Encrypt(string text)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes("WiPB5/SrFvq6fu93"); // Dummy IV value
aes.Key = Encoding.UTF8.GetBytes("I9qKwOuZpWtt64Nl"); // Dummy key
aes.Mode = CipherMode.CFB;
aes.Padding = PaddingMode.PKCS7;
byte[] src = Encoding.Unicode.GetBytes(text);
using (ICryptoTransform encrypt = aes.CreateEncryptor())
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
return Convert.ToBase64String(dest);
}
}
我正在 .NET 8 中构建一个新的桌面应用程序,该应用程序需要解密旧代码创建的数据,但由于不同 .NET 版本之间的 aes 加密/解密工作方式似乎不兼容,该应用程序无法正常工作。
在.NET 4.6中,由 encrypt.TransformFinalBlock() 返回的字节数组 dest 有 32 个字节。 根据我对 PKCS7 documentation 的理解,32 字节数组的其余部分以及所有填充字节将具有相同的值。然而,填充的字节被看似随机的值填充。它们在调试器中看到如下: {245, 51, 180, 226, 20, 222, 24, 183, 72, 152, 102, 17, 219, 215, 37, 233, 123, 119, 154, 204, 218, 52, 139, 81, 119 , 59, 42, 206, 13, 185, 247, 122}
我不确定我对其工作原理的理解是否正确。
当我在 .NET 8 中运行相同的代码时,它返回一个 17 字节数组,该数组不是块大小的倍数。前 16 个字节与预期相同。 {245、51、180、226、20、222、24、183、72、152、102、17、219、215、37、233、106}
如何使我的 .NET 8 代码向后兼容以解密旧代码生成的值?任何对此的帮助将不胜感激!预先感谢。
感谢@Topaco 指导我找到解决方案。非常感谢您的帮助。以下是我最终解决此问题并使其向后兼容 .NET Framework 的方法。
static void Main(string[] args)
{
Console.WriteLine(Encrypt("B9519163"));
}
public static string Encrypt(string text)
{
var aes = Aes.Create();
aes.BlockSize = 128;
aes.KeySize = 256;
aes.IV = Encoding.UTF8.GetBytes("WiPB5/SrFvq6fu93");
aes.Key = Encoding.UTF8.GetBytes("I9qKwOuZpWtt64Nl");
aes.Mode = CipherMode.CFB;
aes.Padding = PaddingMode.None;
byte[] src = Encoding.Unicode.GetBytes(text);
byte[] paddedSrc = PerformPKCS7Padding(src, 16);
using (ICryptoTransform encrypt = aes.CreateEncryptor())
{
byte[] dest = encrypt.TransformFinalBlock(paddedSrc, 0, paddedSrc.Length);
return Convert.ToBase64String(dest);
}
}
static byte[] PerformPKCS7Padding(byte[] input, int blockSize)
{
int paddingLength = blockSize - (input.Length % blockSize);
byte[] paddedData = new byte[input.Length + paddingLength];
// Copy original data
Array.Copy(input, paddedData, input.Length);
// Add padding bytes
for (int i = input.Length; i < paddedData.Length; i++)
{
paddedData[i] = (byte)paddingLength;
}
return paddedData;
}