0

I don't know what I'm doing wrong but I've been trying to get this thing working for about 4 hours now and I just can't get it to work... this just gives me the error: "Please suppy a correct password" when I try to decrypt. Encryption seems to work fine though.

Any suggestions? :<

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Security;
using AesApp.Rijndael;
using System.Linq;

    internal class FileEncryption
        {
            private static string password = pw;

            internal static void Encrypt(string inputfile, string outputfile)
            {
                byte[] encryptedPassword;

                // Create a new instance of the RijndaelManaged
                // class.  This generates a new key and initialization
                // vector (IV).
                using (var algorithm = new RijndaelManaged())
                {
                    algorithm.KeySize = 256;
                    algorithm.BlockSize = 128;

                    // Encrypt the string to an array of bytes.
                    encryptedPassword = Cryptology.EncryptStringToBytes(
                        password, algorithm.Key, algorithm.IV);
                }

                string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
                Cryptology.EncryptFile(@inputfile, @outputfile, chars);
            }

            internal static void Decrypt(string @inputfile, string @outputfile)
            {
                byte[] encryptedPassword;

                // Create a new instance of the RijndaelManaged
                // class.  This generates a new key and initialization
                // vector (IV).
                using (var algorithm = new RijndaelManaged())
                {
                    algorithm.KeySize = 256;
                    algorithm.BlockSize = 128;

                    // Encrypt the string to an array of bytes.
                    encryptedPassword = Cryptology.EncryptStringToBytes(
                        password, algorithm.Key, algorithm.IV);
                }

                string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
                Cryptology.DecryptFile(@inputfile, @outputfile, chars);
            }
        }

Reindael.cs

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

    namespace AesApp.Rijndael
    {
        internal sealed class Cryptology
        {
            private const string Salt = "d5fg4df5sg4ds5fg45sdfg4";
            private const int SizeOfBuffer = 1024 * 8;

            internal 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 RijndaelManaged object
                // with the specified key and IV.
                using (var rijAlg = new RijndaelManaged())
                {
                    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 (var msEncrypt = new MemoryStream())
                    {
                        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        {
                            using (var 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;

            }

            internal static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)
            {
                // Check arguments.
                if (cipherText == null || cipherText.Length <= 0)
                    throw new ArgumentNullException("cipherText");
                if (key == null || key.Length <= 0)
                    throw new ArgumentNullException("key");
                if (iv == null || iv.Length <= 0)
                    throw new ArgumentNullException("key");

                // Declare the string used to hold
                // the decrypted text.
                string plaintext;

                // Create an RijndaelManaged object
                // with the specified key and IV.
                using (var rijAlg = new RijndaelManaged())
                {
                    rijAlg.Key = key;
                    rijAlg.IV = iv;

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

                    // Create the streams used for decryption.
                    using (var msDecrypt = new MemoryStream(cipherText))
                    {
                        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                        {
                            using (var srDecrypt = new StreamReader(csDecrypt))
                            {
                                // Read the decrypted bytes from the decrypting stream
                                // and place them in a string.
                                plaintext = srDecrypt.ReadToEnd();
                            }
                        }
                    }

                }
                return plaintext;
            }

            internal static void EncryptFile(string inputPath, string outputPath, string password)
            {
                var input = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
                var output = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write);

                // Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
                // 1.The block size is set to 128 bits
                // 2.You are not using CFB mode, or if you are the feedback size is also 128 bits

                var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
                var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Salt));

                algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);

                using (var encryptedStream = new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    CopyStream(input, encryptedStream);
                }
            }

            internal static void DecryptFile(string inputPath, string outputPath, string password)
            {
                var input = new FileStream(inputPath, FileMode.Open, FileAccess.Read);
                var output = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write);

                // Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
                // 1.The block size is set to 128 bits
                // 2.You are not using CFB mode, or if you are the feedback size is also 128 bits
                var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
                var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Salt));

                algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);

                try
                {
                    using (var decryptedStream = new CryptoStream(output, algorithm.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        CopyStream(input, decryptedStream);
                    }
                }
                catch (CryptographicException)
                {
                    throw new InvalidDataException("Please suppy a correct password");
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }

            private static void CopyStream(Stream input, Stream output)
            {
                using (output)
                using (input)
                {
                    byte[] buffer = new byte[SizeOfBuffer];
                    int read;
                    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        output.Write(buffer, 0, read);
                    }
                }
            }
        }
    }
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • Hi... just to eran time : where are you getting an error? what is working and what is not? File encyption ? byte encryption ? Such an amount of code is difficult to read, please narrow your request. – Kek Jul 04 '12 at 19:20
  • Sorry didn't mention that, Encryption seems to work fine, generating proper-looking files, but on decryption I get this error –  Jul 04 '12 at 19:24
  • 1
    Why are you prefixing `inputfile` and `outputfile` with an `@` like that? – Jon Skeet Jul 04 '12 at 19:28
  • So, given key and iv, calling DecryptStringFromBytes(EncryptStringToBytes("foo",key, iv),key,iv) fails ? – Kek Jul 04 '12 at 19:28
  • @Kek: I'm .. not sure, I'm pretty new honestly, but the error is in the function DecryptFile(string inputPath, string outputPath, string password) at the try() catch(CryptographicException) –  Jul 04 '12 at 19:32
  • @JonSkeet ... I'm .. not sure :P don't think that has anything to do with it though.. or does it oo –  Jul 04 '12 at 19:33
  • @user1071461: No, it doesn't - but you shouldn't doing that sort of thing arbitrarily. That feature is in case you want to use C# keywords as identifiers. – Jon Skeet Jul 04 '12 at 19:38
  • you are using twice using(decryptedStream), one in decrypt and one in copystream... it may be OK, but it seems dangerous – Kek Jul 04 '12 at 19:40
  • Well I pretty much just pasted this thing off the internet, so yeah, anyways, i checked out the actual exception and it says " Padding is invalid and cannot be removed." –  Jul 04 '12 at 19:42
  • Could you simply try to replace chars with "foo" please ? Cryptology.EncryptFile(inputfile, outputfile, "foo"); & Cryptology.DecryptFile(inputfile, outputfile, "foo"); – Kek Jul 04 '12 at 20:02
  • 2
    This is interesting - we are actually trying to fix a piece of code grabbed from the internet, without any possibility of understanding of the OP about what's going on... move to close – Daniel Mošmondor Jul 04 '12 at 20:29
  • @DanielMošmondor: Agreed, this seems directly copied/pasted from the M$ examples. – Maarten Bodewes Jul 04 '12 at 22:25

3 Answers3

0

Not entirely sure, but I think I remember a time when 2 successive calls to encryption gave 2 different results. Therefore, your two successive calls to EncryptStringToBytes may give 2 different passwords : one for encryption and one for decryption... and this cause the failure.

I am not sure these encryptions are necessary... if you have a password hardcoded, it is always possible to anyone to generate other strings that depend on nothing else. You should use this password directly, instead of crypting it a first time:

 internal static void Encrypt(string inputfile, string outputfile)
 {
     Cryptology.EncryptFile(inputfile, outputfile, password);
 }

 internal static void Decrypt(string inputfile, string outputfile)
 {
     Cryptology.DecryptFile(inputfile, outputfile, password);
 }
Kek
  • 3,145
  • 2
  • 20
  • 26
  • Alright, it works with this ^^ Thanks! Sorry about being able to understand, I havn't slept in ages and I'm pretty new to c# –  Jul 05 '12 at 00:10
0
  1. Your Encrypt function seems to be exactly equal to your decrypt function.
  2. Also, why are you converting all bytes to strings and concatenate them? This transformation is not reversible.
usr
  • 168,620
  • 35
  • 240
  • 369
0
string chars = encryptedPassword.Aggregate(string.Empty, (current, b) => current + b.ToString());
            Cryptology.EncryptFile(@inputfile, @outputfile, chars);

The Aggregate() function is the cause. It is creating different values each time you run your application.

kleopatra
  • 51,061
  • 28
  • 99
  • 211