Search code examples
c#arraysencryptioncryptographyrijndael

Image Encrypting Getting Padding Error


I am developing an image encrypting program. I have got two applications. One of them, converting image to byte array and encrypting with Rijndael. After it is saving encrypted byte array to a file. Second application is for decrypting. I am reading byte array from file. After i am decrypt and show image in picturebox.

But i am geting "Padding is invalid and cannot be removed." error in decryption application.

Now i am saving encrypted byte array to a file this code (I am not sure is it true way for 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;
        }

I am giving this method save file location and encrypted byte array. And It is worked. But i dont know, is it correct way ?

And my decryption application reading encrypted byte array from file method;

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;
}

And Error location decryption method;

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;
        }

Encryption Code

  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;
        }

Full Code Decryption Application

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        ###################################################################
    }
}

Full Code Encryption Application

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              ###################################################################
    }
}

What can i do before going to be a crazy man ? Thank you and waiting your precious answers.


Solution

  • Thanks to Maximilian Gerhardt Solution is here;

        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;
            }
        }