C#流阅读器ReadToEnd()缺少最后一个字符

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

我正在尝试使用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);
}
c# streamreader
1个回答
4
投票

问题出在您的加密代码中。尽管您正在呼叫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();

0
投票

我无法真正在此处跟踪您的代码,但这对我有用。

        public static byte[] AesEncrypt(string plainText, byte[] Key, byte[] IV)
        {
            using var aes = Aes.Create();
            aes.Padding = PaddingMode.Zeros;

            var encryptor = aes.CreateEncryptor(Key, IV);

            using var mstream = new MemoryStream();
            using var cstream = new CryptoStream(mstream, encryptor, CryptoStreamMode.Write);
            using var swriter = new StreamWriter(cstream);

            swriter.Write(Convert.ToBase64String(Encoding.ASCII.GetBytes(plainText)));
            swriter.Flush();

            return mstream.ToArray();
        }

        public static string AesDecrypt(byte[] cipherText, byte[] Key, byte[] IV)
        {

            using var aes = Aes.Create();
            aes.Padding = PaddingMode.Zeros;

            var decryptor = aes.CreateDecryptor(Key, IV);

            using var mstream = new MemoryStream(cipherText);
            using var cdecrypt = new CryptoStream(mstream, decryptor, CryptoStreamMode.Read);
            using var sreader = new StreamReader(cdecrypt);

            return Encoding.ASCII.GetString(Convert.FromBase64String(sreader.ReadToEnd()));
        }

TRY IT

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