Шифрование изображения получает ошибку заполнения

Я разрабатываю программу шифрования изображений. У меня есть два приложения. Один из них, преобразование изображения в массив байтов и шифрование с помощью Rijndael. После этого он сохраняет зашифрованный массив байтов в файл. Второе приложение предназначено для расшифровки. Я читаю массив байтов из файла. После того, как я расшифрую и покажу изображение в окне изображения.

Но я получаю «Заполнение недопустимо и не может быть удалено». ошибка в приложении расшифровки.

Теперь я сохраняю зашифрованный массив байтов в файл с этим кодом (я не уверен, что это верный путь для массива байтов в файл?);

protected bool SaveData(string FileName, byte[] Data)
        {
            BinaryWriter Writer = null;

            try
            {
                // Create a new stream to write to the file
                Writer = new BinaryWriter(File.Open(FileName,FileMode.OpenOrCreate));

                // Writer raw data                
                Writer.Write(Data);
                Writer.Flush();
                Writer.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }

Я даю этому методу сохранить местоположение файла и зашифрованный массив байтов. И это сработало. Но я не знаю, это правильный путь?

И мое приложение для дешифрования, читающее зашифрованный массив байтов из файлового метода;

protected byte[] GetData(string FileName)
{
    FileInfo f = new FileInfo(FileName);
    BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
    byte[] a = br.ReadBytes(Convert.ToInt32(f.Length));
    return a;
}

И метод расшифровки местоположения ошибки.

public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            RijndaelCipher.Mode = CipherMode.CBC;
            byte[] salt = Encoding.ASCII.GetBytes(saltValue);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);

            ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));

            MemoryStream memoryStream = new MemoryStream(encryptedBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
            byte[] plainBytes = new byte[encryptedBytes.Length];


            int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length); // I am getting error this line. Padding is invalid and cannot be removed.



            memoryStream.Flush();
            cryptoStream.Flush();
            memoryStream.Close();
            cryptoStream.Close();

            return plainBytes;
        }

Код шифрования

  public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();
            RijndaelCipher.Mode = CipherMode.CBC;
            byte[] salt = Encoding.ASCII.GetBytes(saltValue);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
            ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(inputBytes, 0, inputBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] CipherBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            return CipherBytes;
        }

Приложение для полной расшифровки кода

namespace ImageDecrypte
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string EncPass;
        private string line;
        private string OkunanVeri;
        private byte[] SifreliDosyaDizi;
        private byte[] CozulmusDosyaDizi;
        private const string SaltPass = "CodeWork";
        private string Sfre;
        private string dyol;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog file = new OpenFileDialog();
            file.Filter = "Şifrelenmiş Dosyalar (*.cw)|*.cw";
            file.FilterIndex = 2;
            file.RestoreDirectory = true;
            file.CheckFileExists = false;
            file.Title = "Şifrelenmiş Dosya Seçiniz..";
            file.InitialDirectory =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (file.ShowDialog() == DialogResult.OK)
            {
                dyol = file.FileName;
                string DosyaAdi = file.SafeFileName;
                label1.Text = DosyaAdi;
                Sfre = textBox1.Text;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Sfre = textBox1.Text;
            SifreliDosyaDizi = GetData(dyol);
            CozulmusDosyaDizi = DecryptBytes(SifreliDosyaDizi, Sfre, SaltPass);
            pictureBox1.Image = byteArrayToImage(CozulmusDosyaDizi);
        }

        public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            RijndaelCipher.Mode = CipherMode.CBC;
            byte[] salt = Encoding.ASCII.GetBytes(saltValue);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);

            ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));

            MemoryStream memoryStream = new MemoryStream(encryptedBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
            byte[] plainBytes = new byte[encryptedBytes.Length];


            int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);


            memoryStream.Flush();
            cryptoStream.Flush();
            memoryStream.Close();
            cryptoStream.Close();

            return plainBytes.Take(DecryptedCount).ToArray();
        }

        public Image byteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }

        //File To Byte Array        ###################################################################
        protected byte[] GetData(string FileName)
        {
            FileInfo f = new FileInfo(FileName);
            BinaryReader br = new BinaryReader(File.Open(FileName, FileMode.Open));
            byte[] a = br.ReadBytes(Convert.ToInt32(f.Length));
            return a;
        }
        //File To Byte Array        ###################################################################
    }
}

Приложение для полного шифрования кода

namespace ImageEncrypte
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string EncPass;
        private byte[] byteArrayForImage;
        private byte[] byteArrayCoded;
        private const string SaltPass = "CodeWork";

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog file = new OpenFileDialog();
            file.Filter = "Jpeg Dosyası |*.jpg| Png Dosyası|*.png";
            file.FilterIndex = 2;
            file.RestoreDirectory = true;
            file.CheckFileExists = false;
            file.Title = "Bir İmaj Dosyası Seçiniz..";
            file.InitialDirectory =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            EncPass = textBox1.Text;
            if (file.ShowDialog() == DialogResult.OK)
            {
                string DosyaYolu = file.FileName;
                string DosyaAdi = file.SafeFileName;
                label1.Text = DosyaAdi;
                Image img = Image.FromFile(DosyaYolu);
                pictureBox1.Image = img;
                byteArrayForImage = imageToByteArray(img);
                byteArrayCoded = EncryptBytes(byteArrayForImage, EncPass, SaltPass);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            SaveFileDialog sf = new SaveFileDialog();
            sf.Title = "Şifrelenmiş Dosyayı Kaydet";
            sf.CheckFileExists = false;
            sf.CheckPathExists = true;
            sf.RestoreDirectory = true;
            sf.DefaultExt = "cw";
            sf.FileName = "EncodedFile";
            sf.SupportMultiDottedExtensions = false;
            sf.Filter = "Şifrelenmiş Dosyalar (*.cw)|*.cw";
            sf.InitialDirectory =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (sf.ShowDialog() == DialogResult.OK)
            {
                string DosyaYolu = sf.FileName;

                bool cevap = SaveData(DosyaYolu, byteArrayCoded);
                if (cevap)
                {
                    MessageBox.Show("OK");
                }
                else
                {
                    MessageBox.Show("PROBLEM");
                }


            }
        }


        //Image To Byte Array      ####################################################################
        public byte[] imageToByteArray(System.Drawing.Image imageIn)
        {
            using (var ms = new MemoryStream())
            {
                imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                return ms.ToArray();
            }
        }
        //Image To Byte Array      ####################################################################

        //Byte Array To File        ###################################################################
        protected bool SaveData(string FileName, byte[] Data)
        {
            BinaryWriter Writer = null;

            try
            {
                // Create a new stream to write to the file
                Writer = new BinaryWriter(File.Open(FileName,FileMode.OpenOrCreate));

                // Writer raw data                
                Writer.Write(Data);
                Writer.Flush();
                Writer.Close();
            }
            catch
            {
                return false;
            }

            return true;
        }
        //Bytte Array To File       ###################################################################

        //EncryptBytes              ###################################################################
        public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();
            RijndaelCipher.Mode = CipherMode.CBC;
            byte[] salt = Encoding.ASCII.GetBytes(saltValue);
            PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
            ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(inputBytes, 0, inputBytes.Length);
            cryptoStream.FlushFinalBlock();
            byte[] CipherBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            return CipherBytes;
        }
        //EncryptBytes              ###################################################################
    }
}

Что я могу сделать, прежде чем стать сумасшедшим? Спасибо и жду ваших драгоценных ответов.


person Emre Erol    schedule 26.03.2016    source источник
comment
Криптопоток, вероятно, был бы проще и понятнее.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 26.03.2016
comment
Да, но обычно эта программа основана на передаче почты. Таким образом, зашифрованные файлы отправить другому человеку с почтой. И приложение для расшифровки загружает почтовое вложение и расшифровывает его.   -  person Emre Erol    schedule 26.03.2016
comment
Вы не показали нам функцию Encrypt().   -  person Maximilian Gerhardt    schedule 26.03.2016
comment
@MaximilianGerhardt извините за это. Я редактирую вопрос, теперь вы можете его найти. Я считаю, что шифрование и дешифрование работают. возможно, мой файл записи неверен, но я не уверен, конечно. Пожалуйста, проверьте и спасибо.   -  person Emre Erol    schedule 26.03.2016
comment
Я не получаю это исключение, хотя я заметил, что вы не использовали переменную DecryptedCount для обрезки массива после нее. (pastebin.com/jAw6qcU8). Дайте ему несколько путей к файлам и посмотрите, что произойдет.   -  person Maximilian Gerhardt    schedule 26.03.2016
comment
Создайте короткий образец, файл размером, скажем, 50 байт. Добавьте простые текстовые данные из файла, пароль в шестнадцатеричном формате (48 байт) и зашифрованные данные в шестнадцатеричном формате. IOW достаточно информации, чтобы дублировать шифрование.   -  person zaph    schedule 26.03.2016
comment
Верны ли методы чтения файла и записи файла?   -  person Emre Erol    schedule 26.03.2016
comment
@MaximilianGerhardt, ты думаешь, моя проблема не в использовании DecryptedCount?   -  person Emre Erol    schedule 26.03.2016
comment
Только вторично. У вас есть исключение, с которым я не сталкивался, поэтому вы даже не дошли до того момента, когда можно было использовать эту переменную, потому что возникло исключение. Ваш код загрузки и сохранения файла определенно странный в том смысле, что его можно заменить на File.WriteAllBytes(string path, byte[] content) и byte[] content = File.ReadAllBytes(string path). Но явных ошибок в этих функциях я не заметил. Используйте отладчик, чтобы убедиться, что то, что вы загружаете и сохраняете, действительно имеет правильный размер массива, и дайте нам код, который вызывает Encrypt() и Decrypt().   -  person Maximilian Gerhardt    schedule 26.03.2016
comment
@MaximilianGerhardt спасибо. Я сейчас в пробке. Через час или два я дам вам полный код.   -  person Emre Erol    schedule 26.03.2016
comment
@MaximilianGerhardt Эй, чувак, я редактирую код и пишу туда полный код двух приложений. Можете ли вы проверить еще раз, пожалуйста?   -  person Emre Erol    schedule 26.03.2016
comment
Не воспроизводится. Я восстановил оба приложения, зашифровал файл и расшифровал его без проблем. Попробуйте расшифровать это (file-upload.net/download-11427818/EncodedFile .cw.html) с паролем testpw в вашем приложении, все работает нормально. Однако кодирование паролей проблематично, в том смысле, что ваши специальные символы (Ş ç) и т. д. не охватываются кодовой страницей ASCII, поэтому byte[] salt = Encoding.ASCII.GetBytes(saltValue); опасно, должно быть byte[] salt = Encoding.UTF32.GetBytes(saltValue); (или, возможно, UTF16) . Попробуйте использовать только символы ASCII.   -  person Maximilian Gerhardt    schedule 26.03.2016


Ответы (1)


Спасибо Максимилиану Герхардту. Решение уже здесь;

    public static byte[] EncryptBytes(byte[] inputBytes, string passPhrase, string saltValue)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
        RijndaelCipher.Mode = CipherMode.CBC;
        RijndaelCipher.Padding = PaddingMode.PKCS7;

        byte[] salt = Encoding.UTF32.GetBytes(saltValue);
        //byte[] salt = Encoding.ASCII.GetBytes(saltValue);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);
        ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(inputBytes, 0, inputBytes.Length);
        cryptoStream.FlushFinalBlock();
        cryptoStream.Flush();
        byte[] CipherBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        return CipherBytes;
    }


    public static byte[] DecryptBytes(byte[] encryptedBytes, string passPhrase, string saltValue)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();

        RijndaelCipher.Mode = CipherMode.CBC;
        RijndaelCipher.Padding = PaddingMode.PKCS7;
        byte[] salt = Encoding.UTF32.GetBytes(saltValue);
        //byte[] salt = Encoding.ASCII.GetBytes(saltValue);
        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);

        ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));

        MemoryStream memoryStream = new MemoryStream(encryptedBytes);
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
        byte[] plainBytes = new byte[encryptedBytes.Length];


        int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);


        memoryStream.Flush();
        cryptoStream.Flush();
        memoryStream.Close();
        cryptoStream.Close();

        return plainBytes.Take(DecryptedCount).ToArray();
    }

    public static byte[] GetData(string FileName)
    {
        return File.ReadAllBytes(FileName);
    }

    protected bool SaveData(string FileName, byte[] Data)
    {
        try
        {
            File.WriteAllBytes(FileName, Data);
            return true;
        }
        catch
        {
            return false;
        }
    }
person Emre Erol    schedule 28.03.2016