0

Based on this code:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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);

                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }


        // Return the encrypted bytes from the memory stream.
        return encrypted;

    }

I need to get get the result (encrypted) saved to a file too. I tried to create a filestream and to CopyTo or WriteTo form the memorystream to the filestream but the output is empty:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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);

                    }
                    encrypted = msEncrypt.ToArray();
                    using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
                    {
                        msEncrypt.CopyTo(file);
                    }
                }
            }
        }
WizardingStudios
  • 554
  • 2
  • 7
  • 22
  • 1
    Try disposing or flushing the CryptoStream before you try to access the contents. – Bryce Wagner Apr 19 '15 at 14:58
  • I substituted the memorystream with the filestream directly. Now the output should be right, i need to test the decrypter to know. – WizardingStudios Apr 19 '15 at 14:59
  • possible duplicate of [Save and load MemoryStream to/from a file](http://stackoverflow.com/questions/8624071/save-and-load-memorystream-to-from-a-file) - because it doesn't matter what is in the memory stream. It's the classic copying memory stream to file stream problem. – Black Frog Apr 19 '15 at 15:22
  • I'd note separately that this has a bug in that it can throw "ArgumentNullException" when you pass empty non-null strings, and so on. – Jon Hanna Apr 19 '15 at 16:33

3 Answers3

4

My comments where all wrong :-)

Now... I was forgetting that on Dispose(), the StreamWriter Dispose()s the underlying stream (the CryptoStream) in this case.

static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
    // Check arguments.
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");
    byte[] encrypted;
    // Create an Rijndael object
    // with the specified key and IV.
    using (Rijndael rijAlg = Rijndael.Create())
    {
        rijAlg.Key = Key;
        rijAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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);

                }

                encrypted = msEncrypt.ToArray();
            }

            using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
            {
                file.Write(encrypted, 0, encrypted.Length);
            }
        }
    }
}

So my suggested revision is simply to leave the msEncrypt.ToArray() "as is" and write the byte[] encrypted as a byte[]

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Your solution create an output file not empty but the content is different from my solution. Because i need also to read the file for the Decryption, wich one is the right solution? I tried also csEncrypt.Flush(); msEncrypt.Position = 0; using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write)) { msEncrypt.WriteTo(file); //file.Write(encrypted, 0, encrypted.Length); } don't work – WizardingStudios Apr 19 '15 at 15:11
0

Because i need to have a file (no need for the memorystream) i substitued the memorystream directly with the filestream and now i have a file containing the encrypted text:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        //byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption.
            //using (MemoryStream msEncrypt = new MemoryStream())
            using (FileStream fileEncrypt = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
            {
                using (CryptoStream csEncrypt = new CryptoStream(fileEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);

                    }
                    //encrypted = fileEncrypt.ToArray();
                }
            }
        }


        // Return the encrypted bytes from the memory stream.

        return null;
    }

Edit: here the result for a Text file containing: Hello, my name is moon! Nice to meet you!

With my solution: zªžRí#°ìªPélZ_êY–­eòÞiOLÍô]xÏÛùNeסÔí°"þà

With Xanatos one: +h†+vÁïˆ60œû¦&PÐvd;xäAÊ<²¾’ïõž2×-†êº,]°­

Another try with mine: ¤µØ¬?ùVF‹R(ªÆä˜Éöb·¯Sƒ¸øÂiœô¶Žµ),vÒÕ¥–F3U

Another try with Xanatos tips: D*’``¢Ý4RúŽP2ÚwvŠE§ÚÅâ8íÜèq%ÉO¶}¸J‘—ôå ¼7

mmmm... they change every time i Encrypt.... i don't know before, sorry... Thanks Xanatos, your solution is good!

WizardingStudios
  • 554
  • 2
  • 7
  • 22
0

Because i need to have a file (no need for the memorystream) i substitued the memorystream directly with the filestream and now i have a file containing the encrypted text:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        //byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            // Create the streams used for encryption.
            //using (MemoryStream msEncrypt = new MemoryStream())
            using (FileStream fileEncrypt = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
            {
                using (CryptoStream csEncrypt = new CryptoStream(fileEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);

                    }
                    //encrypted = fileEncrypt.ToArray();
                }
            }
        }


        // Return the encrypted bytes from the memory stream.

        return null;
    }

@Plutonix, your are right.... i decided for the solution of Xanatos which cover my question:

    static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException("Key");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("Key");
        byte[] encrypted;
        // Create an Rijndael object
        // with the specified key and IV.
        using (Rijndael rijAlg = Rijndael.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.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);

                    }
                    encrypted = msEncrypt.ToArray();
                    //csEncrypt.Flush();
                    //msEncrypt.Position = 0;
                    using (FileStream file = new FileStream("file.bin", FileMode.Create, System.IO.FileAccess.Write))
                    {
                        file.Write(encrypted, 0, encrypted.Length);
                    }
                }
            }
        }


        // Return the encrypted bytes from the memory stream.
        return encrypted;

    }
WizardingStudios
  • 554
  • 2
  • 7
  • 22