Search code examples
c#.netcompressiongzipbouncycastle

Decompressing GZIP data inside Mime message. Found Invalid data while Decoding


I need to decompress data inside MIME message. Data marked with compressed-data Here is code I tried:

using (var msi = new MemoryStream(content))
using (var mso = new MemoryStream())
{
    using (var gs = new GZipStream(msi, CompressionMode.Decompress))
    gs.CopyTo(mso);
    var a = mso.ToArray();
}

Getting exception:

Found invalid data while encoding at System.IO.Compression.InflaterZlib.Inflate(FlushCode flushCode) at System.IO.Compression.InflaterZlib.ReadInflateOutput(Byte[] outputBuffer, Int32 offset, Int32 length, FlushCode flushCode, Int32& bytesRead) at System.IO.Compression.InflaterZlib.Inflate(Byte[] bytes, Int32 offset, Int32 length) at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count) at System.IO.Compression.GZipStream.Read(Byte[] array, Int32 offset, Int32 count) at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize) at System.IO.Stream.CopyTo(Stream destination)

I know it's GZIP in this block of data (per RFC). Ok, I asked question here MimeKit to read compressed data

Got some pointers, after looking through MimeKit code, I found that they actually use BouncyCastle decompression under the hood. Specifically, I was able to make it work with following code. (same data sample):

var cdata = File.ReadAllBytes("C://test//as2//CompressedContentPartContent.bin");
CmsCompressedDataParser ed = new CmsCompressedDataParser(cdata);
var aa = CmsTestUtil.StreamToByteArray(ed.GetContent().ContentStream);

I try to avoid using 3rd party libs (company policy), and seems like it's standard GZIP, so I am confused why standard .NET library gives error.

Any suggestions onto why standard .NET GZipStream and DeflateStream give me error (same error)? What is different with CmsCompressedDataParser ?

I tried another 3rd party lib SharpZipLib on this data and it failed but with different error.

Error GZIP header, first magic byte doesn't match at ICSharpCode.SharpZipLib.GZip.GZipInputStream.ReadHeader() at ICSharpCode.SharpZipLib.GZip.GZipInputStream.Read(Byte[] buffer, Int32 offset, Int32 count) at ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(Stream source, Stream destination, Byte[] buffer) at ICSharpCode.SharpZipLib.GZip.GZip.Decompress(Stream inStream, Stream outStream, Boolean isStreamOwner)

I compared 2 such data structures and first bytes (headers) match.

enter image description here


Solution

  • i don't known CmsCompressedDataParser, but c you image, i sure that are not gzip or deflater data. gzip must start with 0x8B 0x1F, deflater first byte low 4bit must 0x8 for example 0x78

    u can try two option, first, in java byte order is BE, in c# you need try byte order as BE too

    second, deflater may work on no wrap mode, mean the magic flag (first 2 bytes) and CRC data will not output, so i say that not gzip/deflater.