AES加密的C#UTF8编码问题

本文关键字:编码 问题 C#UTF8 加密 AES | 更新日期: 2023-09-27 18:28:27

我正在创建一个基于TCP的聊天客户端。我正在尝试用AES(更安全)加密一些数据。我有一个AES加密类,它默认使用UTF-8作为传出和传入编码类型。但出于某种原因,当我通过TCPClient(使用UTF-8)传递信息并从另一端获取信息时,它会抛出一个错误:

`System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
   at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.FlushFinalBlock()`

因此,我在不使用TCP客户端的情况下重新创建了这个问题,只需将AES加密的数据通过UTF-8编码系统,该系统获取字节数组的字符串,然后使用UTF-8重新获取字节数组(基本上与网络上发生的事情相同(没有字符串))

这种方法有效:

        string dataToEncrypt = "Hello World";
        byte[] key = Encryption.AesEncryption.GenerateKey(32);
        byte[] iv = Encryption.AesEncryption.GenerateKey(16);
        byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);
        string decrypted = Encryption.AesEncryption.DecryptedBytes(encrypted, key, iv);

该方法不起作用(从上面抛出错误)

        Encoding encoding = Encoding.UTF8;
        string dataToEncrypt = "Hello World";
        byte[] key = Encryption.AesEncryption.GenerateKey(32);
        byte[] iv = Encryption.AesEncryption.GenerateKey(16);
        byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);
        string encstring = encoding.GetString(encrypted);
        byte[] utf8encrypted = encoding.GetBytes(encstring);
        string decrypted = Encryption.AesEncryption.DecryptedBytes(utf8encrypted, key, iv);

我做错了什么?

这是我的加密类:

public sealed class AesEncryption
{
    private byte[] Key;
    public Encoding Encoder = Encoding.UTF8;
    public AesEncryption(byte[] key)
    {
        Key = key;
    }
    public byte[] Encrypt(string text, byte[] iv)
    {
        var bytes = Encoder.GetBytes(text);
        var rm = new RijndaelManaged();
        var encrypter = rm.CreateEncryptor(Key, iv);
        var ms = new MemoryStream();
        var cs = new CryptoStream(ms, encrypter, CryptoStreamMode.Write);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        var output = ms.ToArray();
        cs.Close();
        ms.Close();
        return output;
    }
    public string Decrypt(byte[] encrypted, byte[] iv)
    {
        var ms = new MemoryStream();
        var cs = new CryptoStream(ms,
            new RijndaelManaged().CreateDecryptor(Key, iv),
            CryptoStreamMode.Write);
        cs.Write(encrypted, 0, encrypted.Length);
        cs.FlushFinalBlock();
        var output = ms.ToArray();
        cs.Close();
        ms.Close();
        return Encoder.GetString(output);
    }
    public static byte[] EncryptString(string text, byte[] key, byte[] iv)
    {
        var ec = new AesEncryption(key);
        return ec.Encrypt(text, iv);
    }
    public static string DecryptedBytes(byte[] encrypted, byte[] key, byte[] iv)
    {
        var ec = new AesEncryption(key);
        return ec.Decrypt(encrypted, iv);
    }
    public static byte[] GenerateKey(int length)
    {
        Random rnd = new Random();
        var chars = "1!2@3#4$5%6^7&8*9(0)-_=+qQwWeErRtTyYuUiIoOpP[{]}''|aAsSdDfFgGhHjJkKlL;:''"zZxXcCvVbBnNmM,<.>/?".ToCharArray();
        string randomizedKey = "";
        for (int i = 0; i < length; i++)
        {
            randomizedKey += chars[rnd.Next(0, chars.Length)];
        }
        return randomizedKey.ToByteArray();
    }
}

AES加密的C#UTF8编码问题

UTF-8不能完美地表示字节。简单明了的答案是:传输字节,而不是UTF-8字符串。如果必须有一个字符串,请用Base64对其进行编码。