Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-AESCng为什么不正确地加密/解密大于127的字节数组?_C#_Aes - Fatal编程技术网

C#-AESCng为什么不正确地加密/解密大于127的字节数组?

C#-AESCng为什么不正确地加密/解密大于127的字节数组?,c#,aes,C#,Aes,当我用AES加密和解密字节[128]{1,2,…,126,127}时,一切正常: // Create Key & iv byte[] key = GenerateKey(); byte[] iv = GenerateIV(); // Create raw byte array 0-127 byte[] raw = new byte[128]; for (byte i = 0; i < 128; i++) { raw[i] = i; } // Encrypt var en

当我用AES加密和解密字节[128]{1,2,…,126,127}时,一切正常:

// Create Key & iv
byte[] key = GenerateKey();
byte[] iv = GenerateIV();

// Create raw byte array 0-127
byte[] raw = new byte[128];
for (byte i = 0; i < 128; i++)
{
    raw[i] = i;
}

// Encrypt
var encrypted = Encrypt(raw, key, iv);
// Decrypt
var decrypted = Decrypt(encrypted, key, iv);
现在原始数据是字节[4]{195135195131},每个数字都大于127

// Encrypt
var encrypted = Encrypt(raw, key, iv);
// Decrypt
var decrypted = Decrypt(encrypted, key, iv);
但也能正确解密,解密的是字节[4]{195135195131} 现在我完全搞糊涂了,为什么原始数据字节[127]{128,129,…,253,254}不能正确解密

密钥/IV/加密/解密代码:

static byte[] GenerateKey()
{
    using (AesCng cng = new AesCng())
    {
        cng.GenerateKey();
        return cng.Key;
    }
}

static byte[] GenerateIV()
{
    using (AesCng cng = new AesCng())
    {
        cng.GenerateIV();
        return cng.IV;
    }
}

static byte[] Encrypt(byte[] raw, byte[] key, byte[] iv, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
    byte[] encrypted;

    using (AesCng cng = new AesCng())
    {
        cng.Mode = mode;
        cng.Padding = padding;

        cng.Key = key;
        cng.IV = iv;

        using (ICryptoTransform encryptor = cng.CreateEncryptor())
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                csEncrypt.Write(raw, 0, raw.Length);
            }

            encrypted = msEncrypt.ToArray();
        }
    }

    return encrypted;
}

static byte[] Decrypt(byte[] encrypted, byte[] key, byte[] iv, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
    byte[] decryptedData;
    string plaintext = null;
    byte[] plainData = null;

    using (AesCng cng = new AesCng())
    {
        cng.Mode = mode;
        cng.Padding = padding;

        cng.Key = key;
        decryptedData = encrypted;
        cng.IV = iv;

        using (ICryptoTransform decryptor = cng.CreateDecryptor())
        {
            using (MemoryStream msDecrypt = new MemoryStream(decryptedData))
            {
               using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
               {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                    plainData = Encoding.UTF8.GetBytes(plaintext);
                }
            }
        }
    }

    return plainData;
}
这就是问题所在:

using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
    plaintext = srDecrypt.ReadToEnd();
}
plainData = Encoding.UTF8.GetBytes(plaintext);
您将纯文本数据视为UTF-8,将其转换为字符串,然后将其转换回字节(再次使用UTF-8)。如果纯文本数据真的是UTF-8编码的文本(在您的葡萄牙语示例中就是这样),那么这很好,但对于任意字节数组,情况并非如此。字节序列0x80、0x81、0x82、0x83…0xff无效UTF-8

除非您知道数据是有效的文本,否则不应该将其视为文本-这总是会导致这样的问题。在本例中,“纯文本”这个名称实际上并不意味着文本——这是一个不幸的术语。它只是指“未加密的数据”

如果您只是想有效地从任意流中读取数据并从中创建数组,请使用另一个
MemoryStream
,将数据复制到该流,然后使用
MemoryStream.ToArray
将其转换为
字节[]

using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
    using (var plainData = new MemoryStream())
    {
        csDescrypt.CopyTo(plainData);
        return plainData.ToArray();
    }
}
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
    plaintext = srDecrypt.ReadToEnd();
}
plainData = Encoding.UTF8.GetBytes(plaintext);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
    using (var plainData = new MemoryStream())
    {
        csDescrypt.CopyTo(plainData);
        return plainData.ToArray();
    }
}