1

Closed

The MAC does not match

description

When using the DotNetZip - WinFormsTool.exe to extract the contents of the attached file I get "The MAC does not match" for several files. I have tested the attached file with Windows Explorer, WinZip 11.2 and WinRAR 3.93 all of which extracted the contents without issue. I also wrote a very short C# routine to extract the contents but also get the same message on several of the files in the archive.
 
string strPath = System.IO.Path.GetDirectoryName(ZipFile);
Ionic.Zip.ZipFile tmpAttachment = new Ionic.Zip.ZipFile(ZipFile);
tmpAttachment.Password = Password;
foreach (Ionic.Zip.ZipEntry zipEntry in tmpAttachment.Entries)
{
zipEntry.Extract(strPath);
}
 
Either the MAC is correct or all the other applications are ignoring it.
 
Archive password: C-XPSQ5-BRT5302-

file attachments

Closed Jul 14, 2011 at 2:29 AM by Cheeso
fixed in changeset 80670. The first official binary containing this fix will be v1.9.1.6. The first preliminary binary build with this fix will be v1.9.1.6002.

comments

Shipwreck wrote Jul 5, 2011 at 7:35 PM

Gorgot the password for the archive...

C-XPSQ5-BRT5302-

Cheeso wrote Jul 14, 2011 at 2:15 AM

Ah yep - looks like an edge case. The files that are giving MAC mismatch are zero-length files.
I'll get a fix in for that. Thanks for reporting it.

gonzalo_360 wrote Mar 12, 2012 at 6:08 PM

Hello!
I have the next code but i recived the next issue:

"The MAC does not match"

Thank you for your help!!

public static void UnZipFile(string DirOr, string DirDest, string Pass)
   {

       using (var zip = ZipFile.Read(DirOr))
     {
         foreach (ZipEntry e in zip)
        {
            e.ExtractWithPassword(DirDest, Pass);

         }
    }
   }

TimNCO wrote Jan 17, 2013 at 1:31 AM

I had the same problem. Once I downloaded the source, downloaded WiX, Silverlight developer stuff!! and got it running, it took me a little while to step through the code. But I got there in the end...



Basically on line 946 of ZipEntry.Extract.cs (in the ZipDLL project), in a method named VerifyCrcAfterExtract, there is a call to WinZipAesCipherStream.ReadAndVerifyMac



The ReadAndVerifyMac method assumes the Zip file stream we have been reading from is positioned at the end of the encrypted data for the last file that has been read out (and decrypted and inflated most probably). That is where the MAC for the file that has just been decrypted is stored...

In my case, where I am only extracting one file from the Zip archive, the file stream was disposed of once the file data was readout. So the call below to ReadAndVerifyMac actually creates a whole new file stream that is positioned at the beginning of the file - and as you'd expect the call to ReadAndVerifyMac reads the completely wrong data from the file and fails.

WinZipAesCipherStream wzs = _inputDecryptorStream as WinZipAesCipherStream;

_aesCrypto_forExtract.CalculatedMac = wzs.FinalAuthentication;
_aesCrypto_forExtract.ReadAndVerifyMac(this.ArchiveStream); // throws if MAC is bad

The call above to this.ArchiveStream recreates the file stream from scratch, as it has already been disposed of.

A quick and dirty work around is to seek to the correct position in the file by executing the following line of code before the call to ReadAndVerifyMac -

this.ArchiveStream.Position = __FileDataPosition + _CompressedFileDataSize;

but a much better solution, avoiding the need to open a new file stream, is to read out and store the MAC from the file after the last encrypted/compressed data is read, but before the file stream is disposed of. For me that would be done in a method called

private Int32 ExtractOne(Stream output)

in the file ZipEntry.Extract.cs, just before the end of the try block at line 1073.................



Anyway, I have my fix and only have to worry about my own bugs now!