C# 流 reader ReadToEnd() 缺少最后一个字符

C# stream reader ReadToEnd() missing last character

我正在尝试使用 AES 在 C# 中解密字符串:

public static string AesDecrypt(byte[] cipherText, byte[] Key, byte[] IV)
{
    string plaintext = null;

    // Create an Aes object with the specified key and IV
    using Aes aesAlg = Aes.Create();
    aesAlg.Padding = PaddingMode.Zeros;
    aesAlg.Key = Key;
    aesAlg.IV = IV;

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

    // Create the streams used for decryption
    using MemoryStream msDecrypt = new MemoryStream(cipherText);
    using CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
    using StreamReader srDecrypt = new StreamReader(csDecrypt);

    // Read the decrypted bytes from the decrypting stream and place them in a string
    plaintext = srDecrypt.ReadToEnd();
    return plaintext;
}

编码的数据是JSON,但是当我解密它时,我得到了所有正确的数据,除了缺少JSON内容的结束}

我认为 AES 本身不是我的问题。我对

有疑问
plaintext = srDecrypt.ReadToEnd();

因为只缺少最后一个字符。

我不知道我是否应该明确地刷新任何流,但无论如何这是一个非常奇怪的问题。

这里是完整的加密代码:

public static string AesEncrypt(string plainText, byte[] Key, byte[] IV)
{
    // Create an Aes object with the specified key and IV
    using Aes aesAlg = Aes.Create();
    aesAlg.Padding = PaddingMode.Zeros;
    aesAlg.Key = Key;
    aesAlg.IV = IV;

    // Create an encryptor to perform the stream transform
    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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);
    swEncrypt.Flush();

    return Convert.ToBase64String(msEncrypt.ToArray());
}

这就是我调用解密方法的方式:

public static AuthenticationData ParseAuthenticationToken(string token)
{
    byte[] tokenBytes = Convert.FromBase64String(token);
    string json = AesEncryption.AesDecrypt(tokenBytes, aes.Key, aes.IV);
    return JsonConvert.DeserializeObject<AuthenticationData>(json);
}

问题出在您的加密代码中。尽管您正在呼叫 seEncrypt.Flush(),但您并未呼叫 csEncrypt.FlushFinalBlock()。这会在处理流时自动发生,但是直到您调用 msEncrypt.ToArray() 之后您才会这样做。我会将该代码重写为:

MemoryStream msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
    using StreamWriter swEncrypt = new StreamWriter(csEncrypt);
    swEncrypt.Write(plainText);
    // swEncrypt is disposed here, flushing it. Then csEncrypt is disposed,
    // flushing the final block.
}
return msEncrypt.ToArray();