AESCryptoServiceProvider 加密 PKCS7 填充不一致

问题描述 投票:0回答:1

我继承了一些最初在.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 代码向后兼容以解密旧代码生成的值?任何对此的帮助将不胜感激!预先感谢。

c# .net encryption cryptography aes
1个回答
0
投票

感谢@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;
    }
© www.soinside.com 2019 - 2024. All rights reserved.