UpdateFileStream on encrypted file

Jul 28, 2009 at 6:00 PM

Hi,

first of all I have to say that this library is really great.

I came across a little bug, since i am dealing a lot with encrypted zip files i am usually walking on the edge. I realized that the usage of UpdateFileStream function on an encrypted file is not resulting in an winrar compatible format. I came across a similar issue earlier during the usage of a different library which was not updating the header data of other entries in the zip by running any update method. But for encrypted files this seems to lead to a non zip compatible format. So i thought that might be the same issue here.

I would be very happy if someone could look into that.

Regards,

AirBorne

Coordinator
Jul 28, 2009 at 6:15 PM

can you give me some code or pseudo code to show what does not work, and how it does not work?

for example, you create a zip file, then update a single entry in the zip file, then save, and then... what happens? eg I want to see this from you:

  // create the zip file
  using (var zip = new ZipFile())
  {
    zip.Encryption = EncryptionAlgorithm.WinZipAES256; 
    zip.Password = "password1";
    zip.AddEntry("Readme.txt", "", "This is the content.");
    zip.Save("archive.zip");
  }
  // evverything works fine, the zip file is valid.

  // then I try to update the zip file
  using (var zip = ZipFile.Read("archive.zip"))
  {
    // set the password here?
    
    zip.UpdateFileStream(???);  // what arguments here? 
    zip.Save();
  }
  // the resulting zip is unreadable
Coordinator
Jul 28, 2009 at 6:16 PM

also, what version of the library are you using ?

Coordinator
Jul 28, 2009 at 6:44 PM
Edited Jul 28, 2009 at 7:26 PM

I just ran this on v1.8.4.12

            string zipFileToCreate = "Airborne.zip";
            // Step 1. create the zip file
            using (var zip = new ZipFile())
            {
                zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip.Password = "password1";
                zip.AddEntry("Readme.txt", "", "This is the content.");
                zip.Save(zipFileToCreate);
            }
            // everything works fine, the zip file is valid.

            // Step 2. then update the zip file
            using (MemoryStream ms = StringToMemoryStream("This is the new content.\r\n"))
            {
                using (var zip = ZipFile.Read(zipFileToCreate))
                {
                    zip.UpdateEntry("Readme.txt", "", ms);
                    zip.Save();
                }
            }
            // everything works fine, the zip file is still valid.

The zip file produced at the end of Step 2 contains a single entry with updated content. The encryption on that entry is "None". This is because I did not set an encryption or password to use on that entry or zip file.

I also tried updating a zip file with mutiple entries, and encryption, like so:

            // Step 1. create the zip file
            using (var zip = new ZipFile())
            {
                zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip.Password = "password1";
                zip.AddEntry("Readme.txt", "", "This is the original content.");
                zip.AddEntry("MoreText.txt", "", "Sometimes at night I lay awake thinking about {e077a805-f3fa-4868-a34f-5f78abc3e836}, and it is really starting to bother me....");
                zip.Save(zipFileToCreate);
            }
            // everything works fine, the zip file is valid.

            // Step 2. update the zip file
            using (MemoryStream ms = StringToMemoryStream("This is the new content for the readme.  It will replace the original content.\r\n"))
            {
                using (var zip = ZipFile.Read(zipFileToCreate))
                {
                    zip.Password = "password1";
                    zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                    zip.UpdateEntry("Readme.txt", "", ms);
                    zip.Save();
                }
            }
            // everything works fine, the zip file is still valid.

This also works, no problems in the output zip file. In this case though, both entries in the output zip file are encrypted with AES256.  I also modified step 2, to NOT specify a password or encryption, and that also works.  In that case, the unmodified entry retains the AES encryption, while the updated entry is unencrypted.  

If you can give me some code like this showing what you do to cause the problem, I'll be able to look into it better. 

Also I suggest you use the latest version of the library when building that test case.

 

Coordinator
Jul 28, 2009 at 7:28 PM

ps: note that UpdateFileStream() is now marked "obsolete".  Effectively, there's a new name for the method:  UpdateEntry().  It accepts the same arguments.

Jul 28, 2009 at 8:27 PM

Hi Cheeso,

thank you for the very prompt reply. The problem does not seem to be present in the latest version.
Sorry for bothering you with that, I thought I was using the latest version but obviously I was not. I will
let you know in case I am running across any other observations.

Thank you again, the lib is really great and is even getting better ;)

Best Regards,
AirBorne

Coordinator
Jul 29, 2009 at 2:14 AM

Terrific.  Glad it's working out for you.