Data decrypting

How to throw out the awkward character exists at my decrypted data? It is like this ...(my data-number)... 55437 55005 ��S';�5:c�

AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
UTF8Encoding u = new UTF8Encoding();

aes.Key = Encoding.ASCII.GetBytes("1234567890123456");
aes.Mode = CipherMode.ECB;
aes.Padding = PaddingMode.ANSIX923;

MemoryStream ms1 = new MemoryStream(data);
CryptoStream cs1 = new CryptoStream(ms1, aes.CreateDecryptor(), CryptoStreamMode.Read);  //cs used to decrypt the byte

cs1.Read(data, 0, data.Length);
recipherdata = ms1.ToArray();
ms1.Close();

string decrypteddata = Encoding.UTF8.GetString(recipherdata);

2 answers

  • answered 2018-07-11 03:16 Chad Nedzlek

    It’s because you are decrypting into the same data array as your encrypted data, so you are corrupting it.

    Make a new array to read into, and the problem will go away.

    You also need to listen to the return value from read to know how many bytes you read and pass that to GetString

  • answered 2018-07-11 06:18 kennyzx

    The problem is the size of the decrypted data is smaller than the size of the MemoryStream, which is determined by the encrypted data (data).

    For example, encrypting "The quick brown fox jumps over the lazy dog." using your code will get an encrypted data of 48 bytes, however, after decryption, the decrypted data is only 44 bytes. So you are using a memory stream of 48 bytes to store 44 bytes, then you read them all.

    var recipherdata = ms1.ToArray(); //ms1 is 48 bytes
    

    The result is that you have some garbage characters at the end of the string.

    Solution 1: Calculate the size of the decrypted data.

    The call cs1.Read(data, 0, data.Length); returns the count of the bytes of the decrypt data, which is 44 in the above example. So you know how many bytes you should read.

    As the other answer suggested, it is unwise to use the same byte array as both the source stream (the memory stream just wraps the byte array inside) and the target buffer during the process of decryption. Although it works seemingly, it is confusing, have better use another byte array as buffer.

    Solution 2: Use StreamReader.

    Instead of manipulating byte array and calculating offsets, you can use a StreamReader to read directly from the CryptoStream.

    using (MemoryStream ms1 = new MemoryStream(data))
    using (CryptoStream cs1 = new CryptoStream(ms1, aes.CreateDecryptor(), CryptoStreamMode.Read))  //cs used to decrypt the byte
    {
        using (StreamReader reader = new StreamReader(cs1))
        {
            var decrypteddata = reader.ReadToEnd();
        }
    }
    

    See this code example.