Home > OS >  Encryption Routine Not working, Can't figure out, subtle bug in it
Encryption Routine Not working, Can't figure out, subtle bug in it

Time:10-08

All,

Please look at the code below. The encrypt, decrypt code doesn't work correctly. When I pass in the string "Hello world" I get back "Hello wo". I always lose bytes and can't figure it out why. There has to be a reason for this, subtle bug?

private static void _TestEncryption2()
    {
        var testText = "Hello world";
        var plainBytes = Encoding.Unicode.GetBytes(testText);
        
        var cipher = Rijndael.Create();
        cipher.Padding = PaddingMode.PKCS7;
        //var _key = Convert.FromBase64String(KEY);
        //var _IV = Convert.FromBase64String(IV);
        var _key = cipher.Key;
        var _IV = cipher.IV;

        byte[] cipherBytes;
        byte[] decryptedBytes;


        var enc = cipher.CreateEncryptor(_key, _IV);
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, enc, CryptoStreamMode.Write))
            {
                cryptoStream.Write(plainBytes, 0, plainBytes.Length);
            }
            cipherBytes = memoryStream.ToArray();
        }

        var dec = cipher.CreateDecryptor(_key, _IV);
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, dec, CryptoStreamMode.Write))
            {
                cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);

                decryptedBytes = memoryStream.ToArray();
            }
        }

        var decryptedText = Encoding.Unicode.GetString(decryptedBytes);
    }

CodePudding user response:

Dispose your second cryptoStream before doing memoryStream.ToArray():

        var dec = cipher.CreateDecryptor(_key, _IV);
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, dec, CryptoStreamMode.Write))
            {
                cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
            }

            // Here
            decryptedBytes = memoryStream.ToArray();
        }

The problem is that the second CryptoStream hasn't been flushed before you read its output, and it's still holding onto that final block internally.

Your block size is 16 bytes, and you're using UTF-16 which uses 2 bytes per character, so the fact that you're getting the first block of 8 characters (16 bytes), but not the final block, makes sense here.


Also, Encoding.Unicode is UTF-16, which is a slightly odd choice in this day and age. Your default should be Encoding.UTF8.

  • Related