5

Using AES in C# I wrote two static methods for encryption and decryption.

Encrypt:

static byte[] Encrypt(byte[] plaintext, byte[] Key, byte[] IV)
{
    byte[] encrypted_data = null;
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plaintext);
                }
            }
            encrypted_data = msEncrypt.ToArray();
        }
    }
    return encrypted_data;
}

Decrypt:

static string Decrypt(byte[] encrypted_text, byte[] Key, byte[] IV)
{
    string decrypted_data = null;
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msDecrypt = new MemoryStream(encrypted_text))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {
                    decrypted_data = srDecrypt.ReadToEnd();
                    return decrypted_data;
                }
            }
        }
    }
}
static void Main(string[] args)
{
    byte[] Key = GenerateRandomKey(32);
    byte[] IV = GenerateRandomIV(16);
    byte[] data_to_encrypt = Encoding.UTF8.GetBytes("Hola como estas");
    byte[] encrypted_data = Encrypt(data_to_encrypt, Key, IV);
    File.WriteAllBytes("encrypted.enc", encrypted_data);
    byte[] data_to_decrypt = File.ReadAllBytes("encrypted.enc");
    string decrypted_data = Decrypt(data_to_decrypt, Key, IV);
    Console.WriteLine(decrypted_data);
}

I use them in Main() where I generate a random 256-bit key and an IV of 128. I get the bytes of the string I want to encrypt and use the function to encrypt them, then write them to a file and read them again to decrypt but when trying to display them in the console it only shows the type "System.Byte[]".

Why does this happen instead of showing the decrypted data string?

3
  • 1
    Why are you using the StreamWriter class? Commented Oct 12 at 8:06
  • 1
    @Charlieface - The referenced post only addresses one aspect, namely the manual decoding, and is therefore not a true dupe in my opinion. The other alternatives, i.e. omitting the encoding for encryption when using the StreamWriter (as in the MS example) or omitting the StreamWriter when using the encoded data, are also possible solutions that should be addressed. Commented Oct 12 at 13:52
  • 1
    @Topaco Possibly, but it's a bit too obvious "if you have a byte array just write it directly". Also OP actually says in their post "Could someone explain to me why this happens and does not show the decrypted data string?" which seems to be the crux of the question and the dupe answers that. 3 reopening votes are welcome, but I'm not hammering it back open myself because of it. Commented Oct 12 at 16:28

1 Answer 1

7

The StreamWriter class writes a string to a stream and uses a specific encoding. The constructor StreamWriter(Stream) that you are using applies UTF-8 encoding.

Currently you're using Write(Object) (inherited from TextWriter), which writes the text representation of the object to the text stream by calling the ToString() method returning System.Byte[] for a byte array.

To solve the issue, you can e.g. use the Write(String) overload by passing the plaintext as a string instead of the encoded data, i.e. swEncrypt.Write(Encoding.UTF8.GetString(plaintext)) would fix the issue. Alternatively, the plaintext can be passed directly to Encrypt() as a string, see EncryptStringToBytes_Aes() in this MS example.

If you want to use the binary data instead of the string, you can omit the StreamWriter and directly apply CryptoStream.Write(Byte[],Int32,Int32).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.