【问题标题】:C# UTF8 Encoding issue with AES EncryptionAES 加密的 C# UTF8 编码问题
【发布时间】:2014-12-27 04:18:54
【问题描述】:

我正在创建一个基于 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();
    }
}

【问题讨论】:

  • 这是 AESEncryption 类的第二个版本,另一个做了同样的事情,只是它对 MemoryStream、CryptoStream 和 RijndealManaged 引用使用“使用”语句。
  • 既然第一种方法有效,你为什么要尝试使用第二种方法(它没有也不能)?为什么不直接使用第一个正确的方法?

标签: c# encryption encoding utf-8 aes


【解决方案1】:

UTF-8 不能完美地表示字节。简短而简单的答案是:传输字节,而不是 UTF-8 字符串。如果您必须有一个字符串,请将其编码为 Base64。

【讨论】:

  • 它可能不能完美地表示字节,但是哪种编码可以呢?通过 TCP 客户端读取字节时,我需要指定一个编码(因为我正在使用异步)编辑:这将是最好的*
  • 最好改变你对 TCP 的使用以允许字节传输。第二好的是 Base64 编码:stackoverflow.com/questions/11743160/…
  • TCP 客户端确实使用字节,但您需要编码才能从网络流中读取,如果没有提供,它将无法工作。
  • @Mr.Sir.AlecJr.:你太固执了。
  • @Mr.Sir.AlecJr。我建议您研究 Socket 网络而不是使用 TCPClients,它可能会让事情变得更好。 (只是一个选项)。
猜你喜欢
  • 1970-01-01
  • 2012-01-18
  • 2013-03-02
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多