0

I am a computer apprentice and we started C # 3 months ago. I just asked you to help because I have to carry out a "Whatsapp" type project. The goal is to encrypt and compress a message. I can encrypt the message and compress it, but I can't decompress it. I have an error of type "System.IO.InvalidDataException: 'The magic number in the GZip header is not correct. Make sure that your passage takes place in a GZip stream". I copied the code to another topic and tried to adapt it to my program, but to no avail. Thank you for your understanding.

My project is made with Windows Forms. The comments are in french ( because I am french and my teacher ask french comments ) but I think my code is pretty understandable.

Edit : The problem occur with my method "Decompression" at line 139

My project : https://eduvaud-my.sharepoint.com/:u:/g/personal/mathias_rogey_eduvaud_ch/EaMn6Ic_QHZEgP98u45i73sBHsnpnI3lEeWWZdtkud7WPg?e=isYobC

The post I'm talking about : Compression/Decompression string with C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;

namespace ChatApp
{
    public partial class Form1 : Form
    {
        private static string strPath = @"..\..\..\messages\communication.txt";

        const byte byteNbrMsg = 2;

        private static short shrtNbrRandom = 947;

        public Form1()
        {
            InitializeComponent();

            byte[] r1 = Zip("StringStringStringStringStringStringStringStringStringStringStringStringStringString");
            string r2 = Unzip(r1);

            Decryptage();

            chatBox.Items.Add(r2);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Cryptage(messageBox.Text);
        }

        private void Decryptage()
        {
            // variables
            string[] Tab_strDecryptage = Array.Empty<string>();
            string strMessgeDecrypt = string.Empty;
            byte[] Tab_byteDecompress = Array.Empty<byte>();
            string strMessageDecompress;

            // permet de lire les 10 derniers messages et les mets dans un string de byteNbrMsg
            List<string> strText = File.ReadLines(strPath).Reverse().Take(byteNbrMsg).ToList();

            // decrypte les messages
            using (StreamReader sr = new StreamReader(strPath))
            {
                // boucle for qui decrypte les x derniers messages
                for (int i = 0; i < byteNbrMsg; i++)
                {
                    // split le string actuel en l'inversant ( vu que on inverse la lecture des string dans le string )
                    //Tab_strDecryptage = strText[i].Split('\\').ToArray();

                    strMessageDecompress = strText[i];

                    Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);

                    Unzip(Tab_byteDecompress);

                    // boucle foreach qui permet de decrypter chaque entrée du tableau
                    foreach (string item in Tab_strDecryptage)
                    {
                        try
                        {
                            // ajoute au string chaque caractère decrypté lu de la ligne
                            strMessgeDecrypt += ((char)(Math.Sqrt(Convert.ToUInt64(item)) / shrtNbrRandom));
                        }
                        catch (Exception)
                        {

                        }
                    }

                    // ecrit le string
                    chatBox.Items.Add(strMessgeDecrypt);

                    // vide le string
                    strMessgeDecrypt = "";
                }
            }
            // 45 ms pour completer
        }

        private void Cryptage(string strUser)
        {
            // variables
            byte[] byteASCII;
            string strCryptage = string.Empty;
            string strETML = Path.GetFileName(Environment.GetEnvironmentVariable("USERPROFILE"));
            byte[] Tab_byteCompress = new byte[1];
            string strCompress;

            // ecrit les caractère en ASCII
            byteASCII = Encoding.ASCII.GetBytes(strETML + " : " + strUser);

            // crypte les messages
            foreach (byte item in byteASCII)
            {
                // ecrit dans le string chaque caractères crypté séparé par un " \ "
                strCryptage += ((ulong)(Math.Pow(item * shrtNbrRandom, 2)) + "\\");
            }

            // permet de compresser le string crypté
            strCompress = Encoding.ASCII.GetString(Zip(strCryptage));

            // ecrit le string dans le document texte
            using (StreamWriter write = new StreamWriter(strPath, true))
            {
                write.WriteLine(strCompress);
            }
        }

        private void messageBox_TextChanged(object sender, EventArgs e)
        {
            if (messageBox.Text != "")
            {
                sendButton.Visible = true;
            }
            else
            {
                sendButton.Visible = false;
            }
        }


        public void CopyTo(Stream src, Stream dest)
        {
            byte[] bytes = new byte[4096];

            int cnt;

            // erreur: System.IO.InvalidDataException : 'Le nombre magique dans l'en-tête GZip n'est pas correct. Assurez-vous que votre passage s'opère dans un flux GZip.'
            while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
            {
                dest.Write(bytes, 0, cnt);
            }
        }

        public byte[] Zip(string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);

            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(mso, CompressionMode.Compress))
                {
                    //msi.CopyTo(gs);
                    CopyTo(msi, gs);
                }

                return mso.ToArray();
            }
        }

        public string Unzip(byte[] bytes)
        {
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            // mso n'a aucune valeur en input
            // le but est de copier GS qui a des valeurs a MSO
            {
                using (var gs = new GZipStream(msi, CompressionMode.Decompress))
                {
                    //gs.CopyTo(mso);
                    CopyTo(gs, mso);
                }

                return Encoding.UTF8.GetString(mso.ToArray());
            }
        }
    }
}
Mathias
  • 3
  • 4
  • As a side note you might want to compare with trying to compress before encryption. From experience most cases compression before encryption yield much smaller data. If data is already small to begin with then typically encryption then compression yield better result. – Franck Apr 07 '20 at 13:42
  • I tried to do compression before but didn't succed and I was thiniking because my encryption is not great, I needed to compress the encrypted data ( each ASCI char are timed a number and squared ). – Mathias Apr 07 '20 at 13:49
  • Trying to invent your own encryption/decryption is that a requirement for the homework ? If not then just use basic encryption, as it's not a real world case something like a very simple Rijndael should do it. – Franck Apr 07 '20 at 14:23
  • Well no, I don't need to invent a encryption/decryption system, but I didn't knew about Rijndael. I wil try with it. Thank's :) – Mathias Apr 07 '20 at 14:47

1 Answers1

0

Currently, you are writing to the file your encrypted byte[] using ASCII.GetString() and reading from the file using ASCII.GetBytes(). The problem occurs here; the byte[] value you wrote to the file is different than the one you get after reading from the file and converting to byte[].

Instead of ASCII if you use Base64String it should work. You need to change two lines(I commented out those lines and added new version just below):

In the method Decryptage:

//Tab_byteDecompress = Encoding.ASCII.GetBytes(strMessageDecompress);
Tab_byteDecompress = Convert.FromBase64String(strMessageDecompress);

In the method Cryptage:

//strCompress = Encoding.ASCII.GetString(Zip(strCryptage));
strCompress = Convert.ToBase64String(Zip(strCryptage));
Nazim
  • 639
  • 2
  • 10
  • 26