AES 解密有时不起作用(填充无效且无法删除)

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

需要有关加密/解密问题的帮助。

我需要加密 GUID 字符串并将其保存到数据库,然后将其解密并用于识别数据。

但是,加密的字符串有时能够解密,有时则不能。看起来我的代码中缺少一些东西:

public string Encrypt(string stringToEncrypt, string sEncryptionKey)
        {
            byte[] key = Encoding.UTF8.GetBytes(sEncryptionKey.PadLeft(32));
            byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
            byte[] encrypted;

            using (Aes aes = Aes.Create())
            {
                ICryptoTransform encryptor = aes.CreateEncryptor(key, IV);

                using MemoryStream msEncrypt = new();
                using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
                csEncrypt.Write(inputByteArray, 0, inputByteArray.Length);
                csEncrypt.FlushFinalBlock();
                encrypted = msEncrypt.ToArray();
            }

            return HttpUtility.UrlEncode(Convert.ToBase64String(encrypted));
        }

public string Decrypt(string stringToDecrypt, string sEncryptionKey)
        {
            string result = string.Empty;

            byte[] key = Encoding.UTF8.GetBytes(sEncryptionKey.PadLeft(32));
            byte[] inputByteArray = Convert.FromBase64String(HttpUtility.UrlDecode(stringToDecrypt));
            Encoding encoding = Encoding.UTF8;

            using (Aes aes = Aes.Create())
            {
                ICryptoTransform decryptor = aes.CreateDecryptor(key, IV);

                using MemoryStream msDecrypt = new();
                using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Write);
                csDecrypt.Write(inputByteArray, 0, inputByteArray.Length);
                csDecrypt.FlushFinalBlock();
                result = encoding.GetString(msDecrypt.ToArray());
            }

            return result;

        }

两个函数都使用相同的 IV 和加密密钥,并且我已经使用这些加密字符串测试了我的代码

  1. O900I6c8rXR1s9BrZCSzQxLdu7qLlGwxBNqtDMoMGLKsjDebDC69SgPimW1uMgNj <- not working
  2. YLK5RiCvnKyKxKX3vybSIRxlyccut62Qdg4X%2bPPBwmU6fr%2fKBILsKoY3LGdtHN%2b1 <- working
  3. %2bqX0P5NEg8KxK1h6OTCsDSid0CZv6idKtnrn4FHjK7NvvcCb7LJHsiRtzBlrA79k <- working

不知何故,尽管使用相同的加密功能,但只有第一个不起作用。异常发生在解密方法的 FlushFinalBlock() 行上。

加密是在.NET 6应用程序中完成的

解密在.NET 4.6.1应用程序中完成

这是要测试的示例密钥和 IV:

键 = d4n40nly

IV = 新字节[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };

有人可以启发我吗?

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

尝试这样:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
                    
public class Program
{
    private static byte[] IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
    private static string key = "d4n40nly";

    public static string Encrypt(string plainText, string strKey)
    {
        byte[] bytesKey = Encoding.UTF8.GetBytes(strKey.PadLeft(32));  
        byte[] bytesPlainText = Encoding.UTF8.GetBytes(plainText);      
        byte[] bytesEncrypted;

        // Create an Aes object with the specified padding, key and IV.
        using (Aes aes = Aes.Create())
        {
            aes.Padding = PaddingMode.PKCS7;
            aes.BlockSize = 128; // 16 bytes = 128 bit 
            aes.Key = bytesKey;  // 32 bytes = 256 bit
            aes.IV = IV;         // 16 bytes = 128 bit

            // Create an encryptor to perform the stream transform.
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    bytesEncrypted = msEncrypt.ToArray();
                }
            }
        }
        return Convert.ToBase64String(bytesEncrypted); 
    }

    public static string Decrypt(string cipherText, string strKey)
    {
        byte[] bytesKey = Encoding.UTF8.GetBytes(strKey.PadLeft(32));
        byte[] bytesCipherText = Convert.FromBase64String(cipherText);
        string plaintext = string.Empty;

        // Create an Aes object with the specified padding, key and IV.
        using (Aes aes = Aes.Create())
        {
            aes.Padding = PaddingMode.PKCS7;
            aes.BlockSize = 128; // 16 bytes = 128 bit 
            aes.Key = bytesKey;  // 32 bytes = 256 bit
            aes.IV = IV;         // 16 bytes = 128 bit

            // Create a decryptor to perform the stream transform.
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(bytesCipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        // Read the decrypted bytes from the decrypting stream
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return plaintext;
    }

    public static void Main()
    {
        //for(int i=0; i<nt.MaxValue; i++) {
            string plainText =  Guid.NewGuid().ToString();
            Console.WriteLine("plaintext: " + plainText);

            string strEncrypted = Encrypt(plainText, key);
            Console.WriteLine("encrypted: " + strEncrypted);

            string strDecrypted = Decrypt(strEncrypted, key);
            Console.WriteLine("decrypted: " + strDecrypted);
            
            if(plainText.Equals(strDecrypted)){
                Console.WriteLine("passed\n");
            }    
            else {
                Console.WriteLine("failed!\n\n");
                //break;
            }
        //}
    }
}

输出:

plaintext: b50cc962-59be-4c82-a846-117fbc3011dd
encrypted: Oco7yFjxWP4UD1OYRInzM3ukRByATBWOiWRPqrRyNYRoQdf0VfRUvptL3L3xUiq5
decrypted: b50cc962-59be-4c82-a846-117fbc3011dd
passed

我用random Guid进行测试,直到循环int.MaxValue-1,结果所有测试都成功。

© www.soinside.com 2019 - 2024. All rights reserved.