示例#1
0
        private byte[] CreateStrongEncryptionDataSpaceStream()
        {
            MemoryStream ms = RecyclableMemory.GetStream();
            BinaryWriter bw = new BinaryWriter(ms);

            bw.Write((int)8);       //HeaderLength
            bw.Write((int)1);       //EntryCount

            string tr = "StrongEncryptionTransform";

            bw.Write((int)tr.Length * 2);
            bw.Write(UTF8Encoding.Unicode.GetBytes(tr + "\0")); // end \0 is for padding

            bw.Flush();
            return(ms.ToArray());
        }
示例#2
0
        internal byte[] EncryptedVerifierHash; //(variable): An array of bytes that contains the encrypted form of the hash of the randomly generated Verifier value. The length of the array MUST be the size of the encryption block size multiplied by the number of blocks needed to encrypt the hash of the Verifier. If the encryption algorithm is RC4, the length MUST be 20 bytes. If the encryption algorithm is AES, the length MUST be 32 bytes.
        internal byte[] WriteBinary()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                bw.Write(SaltSize);
                bw.Write(Salt);
                bw.Write(EncryptedVerifier);
                bw.Write(0x14);                 //Sha1 is 20 bytes  (Encrypted is 32)
                bw.Write(EncryptedVerifierHash);

                bw.Flush();
                return(ms.ToArray());
            }
        }
示例#3
0
        /// <summary>
        /// Return the dimension of the embedded image in pixel
        /// </summary>
        /// <returns>image dimension</returns>
        public Size GetImageDimension()
        {
            InternalWorkbook iwb = (_patriarch.Sheet.Workbook as HSSFWorkbook).Workbook;
            EscherBSERecord  bse = iwb.GetBSERecord(PictureIndex);

            byte[] data = bse.BlipRecord.PictureData;
            //int type = bse.BlipTypeWin32;

            using (MemoryStream ms = RecyclableMemory.GetStream(data))
            {
                using (Image img = Image.Load(ms))
                {
                    return(img.Size());
                }
            }
        }
示例#4
0
        /// <summary>
        /// 2.4.3.2 Encryption
        /// </summary>
        /// <param name="value"></param>
        /// <returns>Byte hex string</returns>
        private string Encrypt(byte[] value)
        {
            byte[] seed = new byte[1];
            var    rn   = RandomNumberGenerator.Create();

            rn.GetBytes(seed);

            byte[] array;
            byte   pb;

            byte[] enc = new byte[value.Length + 10];
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter br = new BinaryWriter(ms);
                enc[0] = seed[0];
                enc[1] = (byte)(2 ^ seed[0]);

                byte projKey = 0;

                foreach (var c in ProjectID)
                {
                    projKey += (byte)c;
                }
                enc[2] = (byte)(projKey ^ seed[0]);
                var ignoredLength = (seed[0] & 6) / 2;
                for (int i = 0; i < ignoredLength; i++)
                {
                    br.Write(seed[0]);
                }
                br.Write(value.Length);
                br.Write(value);
                array = ms.ToArray();
                pb    = projKey;
            }

            int pos = 3;

            foreach (var b in array)
            {
                enc[pos] = (byte)(b ^ (enc[pos - 2] + pb));
                pos++;
                pb = b;
            }

            return(GetString(enc, pos - 1));
        }
示例#5
0
        private byte[] CreateVersionStream()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                bw.Write((short)0x3C);  //Major
                bw.Write((short)0);     //Minor
                bw.Write(UTF8Encoding.Unicode.GetBytes("Microsoft.Container.DataSpaces"));
                bw.Write((int)1);       //ReaderVersion
                bw.Write((int)1);       //UpdaterVersion
                bw.Write((int)1);       //WriterVersion

                bw.Flush();
                return(ms.ToArray());
            }
        }
示例#6
0
        //private static ConcatBytes()

        /**
         * The {@link RC4} instance needs to be Changed every 1024 bytes.
         * @param keyBlockNo used to seed the newly Created {@link RC4}
         */
        internal RC4 CreateRC4(int keyBlockNo)
        {
            using (MD5 md5 = new MD5CryptoServiceProvider())
            {
                using (MemoryStream baos = RecyclableMemory.GetStream(4))
                {
                    new LittleEndianOutputStream(baos).WriteInt(keyBlockNo);
                    byte[] baosToArray = baos.ToArray();
                    byte[] data        = new byte[baosToArray.Length + _keyDigest.Length];
                    Array.Copy(_keyDigest, 0, data, 0, _keyDigest.Length);
                    Array.Copy(baosToArray, 0, data, _keyDigest.Length, baosToArray.Length);

                    byte[] digest = md5.ComputeHash(data);
                    return(new RC4(digest));
                }
            }
        }
示例#7
0
 public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor)
 {
     // workitem 8460
     byte[] working = new byte[1024];
     using (var output = RecyclableMemory.GetStream())
     {
         using (decompressor)
         {
             int n;
             while ((n = decompressor.Read(working, 0, working.Length)) != 0)
             {
                 output.Write(working, 0, n);
             }
         }
         return(output.ToArray());
     }
 }
示例#8
0
        private MemoryStream DecryptBinary(EncryptionInfoBinary encryptionInfo, string password, long size, byte[] encryptedData)
        {
            var doc = RecyclableMemory.GetStream();

            if (encryptionInfo.Header.AlgID == AlgorithmID.AES128 || (encryptionInfo.Header.AlgID == AlgorithmID.Flags && ((encryptionInfo.Flags & (Flags.fAES | Flags.fExternal | Flags.fCryptoAPI)) == (Flags.fAES | Flags.fCryptoAPI)))
                ||
                encryptionInfo.Header.AlgID == AlgorithmID.AES192
                ||
                encryptionInfo.Header.AlgID == AlgorithmID.AES256
                )
            {
#if (Core)
                var decryptKey = Aes.Create();
#else
                RijndaelManaged decryptKey = new RijndaelManaged();
#endif
                decryptKey.KeySize = encryptionInfo.Header.KeySize;
                decryptKey.Mode    = CipherMode.ECB;
                decryptKey.Padding = PaddingMode.None;

                var key = GetPasswordHashBinary(password, encryptionInfo);
                if (IsPasswordValid(key, encryptionInfo))
                {
                    ICryptoTransform decryptor = decryptKey.CreateDecryptor(
                        key,
                        null);

                    using (var dataStream = RecyclableMemory.GetStream(encryptedData))
                    {
                        var cryptoStream = new CryptoStream(dataStream,
                                                            decryptor,
                                                            CryptoStreamMode.Read);

                        var decryptedData = new byte[size];

                        cryptoStream.Read(decryptedData, 0, (int)size);
                        doc.Write(decryptedData, 0, (int)size);
                    }
                }
                else
                {
                    throw (new UnauthorizedAccessException("Invalid password"));
                }
            }
            return(doc);
        }
示例#9
0
        private void ReadDirectory(List <byte[]> sectors, int index, List <CompoundDocumentItem> l)
        {
            using (var ms = RecyclableMemory.GetStream(sectors[index]))
            {
                var br = new BinaryReader(ms);

                while (ms.Position < ms.Length)
                {
                    var e = new CompoundDocumentItem();
                    e.Read(br);
                    if (e.ObjectType != 0)
                    {
                        l.Add(e);
                    }
                }
            }
        }
示例#10
0
        private byte[] CreateProjectwmStream()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                foreach (var module in Modules)
                {
                    bw.Write(Encoding.GetEncoding(CodePage).GetBytes(module.Name)); //Name
                    bw.Write((byte)0);                                              //Null
                    bw.Write(Encoding.Unicode.GetBytes(module.Name));               //Name
                    bw.Write((ushort)0);                                            //Null
                }
                bw.Write((ushort)0);                                                //Null
                return(ms.ToArray());
            }
        }
示例#11
0
        // Set the dataintegrity
        private void SetHMAC(EncryptionInfoAgile ei, HashAlgorithm hashProvider, byte[] salt, byte[] data)
        {
            var iv = GetFinalHash(hashProvider, BlockKey_HmacKey, ei.KeyData.SaltValue);
            var ms = RecyclableMemory.GetStream();

            EncryptAgileFromKey(ei.KeyEncryptors[0], ei.KeyEncryptors[0].KeyValue, salt, 0L, salt.Length, iv, ms);
            ei.DataIntegrity.EncryptedHmacKey = ms.ToArray();
            ms.Dispose();

            var h         = GetHmacProvider(ei.KeyEncryptors[0], salt);
            var hmacValue = h.ComputeHash(data);

            ms = RecyclableMemory.GetStream();
            iv = GetFinalHash(hashProvider, BlockKey_HmacValue, ei.KeyData.SaltValue);
            EncryptAgileFromKey(ei.KeyEncryptors[0], ei.KeyEncryptors[0].KeyValue, hmacValue, 0L, hmacValue.Length, iv, ms);
            ei.DataIntegrity.EncryptedHmacValue = ms.ToArray();
            ms.Dispose();
        }
示例#12
0
        private List <int> ReadFAT(List <byte[]> sectors, DocWriteInfo dwi)
        {
            var l = new List <int>();

            foreach (var i in dwi.DIFAT)
            {
                using (var ms = RecyclableMemory.GetStream(sectors[i]))
                {
                    var br = new BinaryReader(ms);
                    while (ms.Position < _sectorSize)
                    {
                        var d = br.ReadInt32();
                        l.Add(d);
                    }
                }
            }
            return(l);
        }
示例#13
0
        public Record CloneViaReserialise()
        {
            // Do it via a re-serialization
            // It's a cheat, but it works...
            byte[] b = Serialize();
            using (MemoryStream ms = RecyclableMemory.GetStream(b))
            {
                RecordInputStream rinp = new RecordInputStream(ms);
                rinp.NextRecord();

                Record[] r = RecordFactory.CreateRecord(rinp);
                if (r.Length != 1)
                {
                    throw new InvalidOperationException("Re-serialised a record to clone it, but got " + r.Length + " records back!");
                }
                return(r[0]);
            }
        }
示例#14
0
        internal byte[] WriteBinary()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                bw.Write(MajorVersion);
                bw.Write(MinorVersion);
                bw.Write((int)Flags);
                byte[] header = Header.WriteBinary();
                bw.Write((uint)header.Length);
                bw.Write(header);
                bw.Write(Verifier.WriteBinary());

                bw.Flush();
                return(ms.ToArray());
            }
        }
        private static Ptg ReadRefPtg(byte[] formulaRawBytes)
        {
            using (MemoryStream ms = RecyclableMemory.GetStream(formulaRawBytes))
            {
                ILittleEndianInput in1 = new LittleEndianInputStream(ms);
                byte ptgSid            = (byte)in1.ReadByte();
                switch (ptgSid)
                {
                case AreaPtg.sid: return(new AreaPtg(in1));

                case Area3DPtg.sid: return(new Area3DPtg(in1));

                case RefPtg.sid: return(new RefPtg(in1));

                case Ref3DPtg.sid: return(new Ref3DPtg(in1));
                }
                return(null);
            }
        }
示例#16
0
        /** Reads all byte data for the current record, including any
         *  that overlaps into any following continue records.
         *
         *  @deprecated Best to write a input stream that wraps this one where there Is
         *  special sub record that may overlap continue records.
         */
        public byte[] ReadAllContinuedRemainder()
        {
            //Using a ByteArrayOutputStream is just an easy way to Get a
            //growable array of the data.
            using (MemoryStream out1 = RecyclableMemory.GetStream(2 * MAX_RECORD_DATA_SIZE))
            {
                while (true)
                {
                    byte[] b = ReadRemainder();
                    out1.Write(b, 0, b.Length);
                    if (!IsContinueNext)
                    {
                        break;
                    }
                    NextRecord();
                }

                return(out1.ToArray());
            }
        }
示例#17
0
        private List <int> ReadMiniFAT(List <byte[]> sectors, DocWriteInfo dwi)
        {
            var l          = new List <int>();
            var nextSector = _firstMiniFATSectorLocation;

            while (nextSector != END_OF_CHAIN)
            {
                using (var ms = RecyclableMemory.GetStream(sectors[nextSector]))
                {
                    var br = new BinaryReader(ms);
                    while (ms.Position < _sectorSize)
                    {
                        var d = br.ReadInt32();
                        l.Add(d);
                    }
                    nextSector = dwi.FAT[nextSector];
                }
            }
            return(l);
        }
示例#18
0
        internal string CSPName;            //SHOULD<11> be set to either "Microsoft Enhanced RSA and AES Cryptographic Provider" or "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)" as a null-terminated Unicode string.
        internal byte[] WriteBinary()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                bw.Write((int)Flags);
                bw.Write(SizeExtra);
                bw.Write((int)AlgID);
                bw.Write((int)AlgIDHash);
                bw.Write((int)KeySize);
                bw.Write((int)ProviderType);
                bw.Write(Reserved1);
                bw.Write(Reserved2);
                bw.Write(Encoding.Unicode.GetBytes(CSPName));

                bw.Flush();
                return(ms.ToArray());
            }
        }
示例#19
0
        private byte[] CreateDataSpaceMap()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                BinaryWriter bw = new BinaryWriter(ms);

                bw.Write((int)8);       //HeaderLength
                bw.Write((int)1);       //EntryCount
                string s1 = "EncryptedPackage";
                string s2 = "StrongEncryptionDataSpace";
                bw.Write((int)(s1.Length + s2.Length) * 2 + 0x16);
                bw.Write((int)1);                                   //ReferenceComponentCount
                bw.Write((int)0);                                   //Stream=0
                bw.Write((int)s1.Length * 2);                       //Length s1
                bw.Write(UTF8Encoding.Unicode.GetBytes(s1));
                bw.Write((int)(s2.Length * 2));                     //Length s2
                bw.Write(UTF8Encoding.Unicode.GetBytes(s2 + "\0")); // end \0 is for padding

                bw.Flush();
                return(ms.ToArray());
            }
        }
示例#20
0
        private void LoadDIFATSectors(DocWriteInfo dwi)
        {
            var nextSector = _firstDIFATSectorLocation;

            while (nextSector > 0)
            {
                using (var ms = RecyclableMemory.GetStream(_sectors[nextSector]))
                {
                    var brDI = new BinaryReader(ms);
                    var sect = -1;
                    while (ms.Position < _sectorSize)
                    {
                        if (sect > 0)
                        {
                            dwi.DIFAT.Add(sect);
                        }
                        sect = brDI.ReadInt32();
                    }
                    nextSector = sect;
                }
            }
        }
示例#21
0
        private MemoryStream EncryptPackageBinary(byte[] package, ExcelEncryption encryption)
        {
            byte[] encryptionKey;
            //Create the Encryption Info. This also returns the Encryptionkey
            var encryptionInfo = CreateEncryptionInfo(encryption.Password,
                                                      encryption.Algorithm == EncryptionAlgorithm.AES128 ?
                                                      AlgorithmID.AES128 :
                                                      encryption.Algorithm == EncryptionAlgorithm.AES192 ?
                                                      AlgorithmID.AES192 :
                                                      AlgorithmID.AES256, out encryptionKey);

            //ILockBytes lb;
            //var iret = CreateILockBytesOnHGlobal(IntPtr.Zero, true, out lb);

            //IStorage storage = null;
            //MemoryStream ret = null;

            var doc = new CompoundDocument();

            CreateDataSpaces(doc);

            doc.Storage.DataStreams.Add("EncryptionInfo", encryptionInfo.WriteBinary());

            //Encrypt the package
            byte[] encryptedPackage = EncryptData(encryptionKey, package, false);
            using (var ms = RecyclableMemory.GetStream())
            {
                ms.Write(BitConverter.GetBytes((ulong)package.Length), 0, 8);
                ms.Write(encryptedPackage, 0, encryptedPackage.Length);
                doc.Storage.DataStreams.Add("EncryptedPackage", ms.ToArray());
            }

            var ret = RecyclableMemory.GetStream();

            doc.Save(ret);

            return(ret);
        }
示例#22
0
        private byte[] EncryptDataAgile(byte[] data, EncryptionInfoAgile encryptionInfo, HashAlgorithm hashProvider)
        {
            var ke = encryptionInfo.KeyEncryptors[0];

#if Core
            var aes = Aes.Create();
#else
            RijndaelManaged aes = new RijndaelManaged();
#endif
            aes.KeySize = ke.KeyBits;
            aes.Mode    = CipherMode.CBC;
            aes.Padding = PaddingMode.Zeros;

            int pos     = 0;
            int segment = 0;

            //Encrypt the data
            using (
                var ms = RecyclableMemory.GetStream())
            {
                ms.Write(BitConverter.GetBytes((ulong)data.Length), 0, 8);
                while (pos < data.Length)
                {
                    var segmentSize = (int)(data.Length - pos > 4096 ? 4096 : data.Length - pos);

                    var ivTmp = new byte[4 + encryptionInfo.KeyData.SaltSize];
                    Array.Copy(encryptionInfo.KeyData.SaltValue, 0, ivTmp, 0, encryptionInfo.KeyData.SaltSize);
                    Array.Copy(BitConverter.GetBytes(segment), 0, ivTmp, encryptionInfo.KeyData.SaltSize, 4);
                    var iv = hashProvider.ComputeHash(ivTmp);

                    EncryptAgileFromKey(ke, ke.KeyValue, data, pos, segmentSize, iv, ms);
                    pos += segmentSize;
                    segment++;
                }
                ms.Flush();
                return(ms.ToArray());
            }
        }
示例#23
0
        public static String UncompressString(byte[] compressed, Stream decompressor)
        {
            // workitem 8460
            byte[] working  = new byte[1024];
            var    encoding = System.Text.Encoding.UTF8;

            using (var output = RecyclableMemory.GetStream())
            {
                using (decompressor)
                {
                    int n;
                    while ((n = decompressor.Read(working, 0, working.Length)) != 0)
                    {
                        output.Write(working, 0, n);
                    }
                }

                // reset to allow read from start
                output.Seek(0, SeekOrigin.Begin);
                var sr = new StreamReader(output, encoding);
                return(sr.ReadToEnd());
            }
        }
示例#24
0
        internal async Task <byte[]> GetAsByteArrayAsync(bool save, CancellationToken cancellationToken)
        {
            if (save)
            {
                Workbook.Save();
                _zipPackage.Close();
                if (_stream is MemoryStream && _stream.Length > 0)
                {
                    _stream.Close();
#if Standard21
                    await _stream.DisposeAsync();
#else
                    _stream.Dispose();
#endif
                    _stream = RecyclableMemory.GetStream();
                }
                _zipPackage.Save(_stream);
            }
            var byRet = new byte[Stream.Length];
            var pos   = Stream.Position;
            Stream.Seek(0, SeekOrigin.Begin);
            await Stream.ReadAsync(byRet, 0, (int)Stream.Length, cancellationToken).ConfigureAwait(false);

            //Encrypt Workbook?
            if (Encryption.IsEncrypted)
            {
                var eph = new EncryptedPackageHandler();
                using (var ms = eph.EncryptPackage(byRet, Encryption))
                {
                    byRet = ms.ToArray();
                }
            }

            Stream.Seek(pos, SeekOrigin.Begin);
            Stream.Close();
            return(byRet);
        }
示例#25
0
        private void SaveImageToPackage(ePictureType type, byte[] img)
        {
            var package = _drawings.Worksheet._package.ZipPackage;

            ContentType = PictureStore.GetContentType(type.ToString());
            IPictureContainer container = this;

            container.UriPic = GetNewUri(package, "/xl/media/image{0}." + type.ToString());
            var    store = _drawings._package.PictureStore;
            var    ii    = store.AddImage(img, container.UriPic, ContentType);
            string relId;

            if (!_drawings._hashes.ContainsKey(ii.Hash))
            {
                Part             = ii.Part;
                container.RelPic = _drawings.Part.CreateRelationship(UriHelper.GetRelativeUri(_drawings.UriDrawing, ii.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
                relId            = container.RelPic.Id;
                _drawings._hashes.Add(ii.Hash, new HashInfo(relId));
                AddNewPicture(img, relId);
            }
            else
            {
                relId = _drawings._hashes[ii.Hash].RelId;
                var rel = _drawings.Part.GetRelationship(relId);
                container.UriPic = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
            }
            container.ImageHash = ii.Hash;
            using (var ms = RecyclableMemory.GetStream(img))
            {
                _image = Image.FromStream(ms);
            }
            SetPosDefaults(_image);

            //Create relationship
            TopNode.SelectSingleNode("xdr:pic/xdr:blipFill/a:blip/@r:embed", NameSpaceManager).Value = relId;
            package.Flush();
        }
示例#26
0
        private byte[] GetCertStore()
        {
            using (var ms = RecyclableMemory.GetStream())
            {
                var bw = new BinaryWriter(ms);

                bw.Write((uint)0);          //Version
                bw.Write((uint)0x54524543); //fileType

                //SerializedCertificateEntry
                var certData = Certificate.RawData;
                bw.Write((uint)0x20);
                bw.Write((uint)1);
                bw.Write((uint)certData.Length);
                bw.Write(certData);

                //EndElementMarkerEntry
                bw.Write((uint)0);
                bw.Write((ulong)0);

                bw.Flush();
                return(ms.ToArray());
            }
        }
示例#27
0
        internal ZipPackage(Stream stream)
        {
            bool hasContentTypeXml = false;

            if (stream == null || stream.Length == 0)
            {
                AddNew();
            }
            else
            {
                var rels = new Dictionary <string, string>();
                stream.Seek(0, SeekOrigin.Begin);
                using (ZipInputStream zip = new ZipInputStream(stream))
                {
                    var e = zip.GetNextEntry();
                    if (e == null)
                    {
                        throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
                    }

                    while (e != null)
                    {
                        GetDirSeparator(e);
                        if (e.UncompressedSize > 0)
                        {
                            var b    = new byte[e.UncompressedSize];
                            var size = zip.Read(b, 0, (int)e.UncompressedSize);
                            if (e.FileName.Equals("[content_types].xml", StringComparison.OrdinalIgnoreCase))
                            {
                                AddContentTypes(Encoding.UTF8.GetString(b));
                                hasContentTypeXml = true;
                            }
                            else if (e.FileName.Equals($"_rels{_dirSeparator}.rels", StringComparison.OrdinalIgnoreCase))
                            {
                                ReadRelation(Encoding.UTF8.GetString(b), "");
                            }
                            else
                            {
                                if (e.FileName.EndsWith(".rels", StringComparison.OrdinalIgnoreCase))
                                {
                                    rels.Add(GetUriKey(e.FileName), Encoding.UTF8.GetString(b));
                                }
                                else
                                {
                                    var part = new ZipPackagePart(this, e);
                                    part.Stream = RecyclableMemory.GetStream();
                                    part.Stream.Write(b, 0, b.Length);
                                    Parts.Add(GetUriKey(e.FileName), part);
                                }
                            }
                        }
                        e = zip.GetNextEntry();
                    }
                    if (_dirSeparator == '0')
                    {
                        _dirSeparator = '/';
                    }
                    foreach (var p in Parts)
                    {
                        string name      = Path.GetFileName(p.Key);
                        string extension = Path.GetExtension(p.Key);
                        string relFile   = string.Format("{0}_rels/{1}.rels", p.Key.Substring(0, p.Key.Length - name.Length), name);
                        if (rels.ContainsKey(relFile))
                        {
                            p.Value.ReadRelation(rels[relFile], p.Value.Uri.OriginalString);
                        }
                        if (_contentTypes.ContainsKey(p.Key))
                        {
                            p.Value.ContentType = _contentTypes[p.Key].Name;
                        }
                        else if (extension.Length > 1 && _contentTypes.ContainsKey(extension.Substring(1)))
                        {
                            p.Value.ContentType = _contentTypes[extension.Substring(1)].Name;
                        }
                    }
                    if (!hasContentTypeXml)
                    {
                        throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
                    }
                    if (!hasContentTypeXml)
                    {
                        throw (new InvalidDataException("The file is not an valid Package file. If the file is encrypted, please supply the password in the constructor."));
                    }
                    zip.Close();
                    zip.Dispose();
                }
            }
        }
示例#28
0
        readonly byte[] BlockKey_HmacValue = new byte[] { 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33 }; //MSOFFCRYPTO 2.3.4.14 section 5

        private MemoryStream DecryptAgile(EncryptionInfoAgile encryptionInfo, string password, long size, byte[] encryptedData, byte[] data)
        {
            if (encryptionInfo.KeyData.CipherAlgorithm == eCipherAlgorithm.AES)
            {
                var encr                = encryptionInfo.KeyEncryptors[0];
                var hashProvider        = GetHashProvider(encr);
                var hashProviderDataKey = GetHashProvider(encryptionInfo.KeyData);

                var baseHash = GetPasswordHash(hashProvider, encr.SaltValue, password, encr.SpinCount, encr.HashSize);

                //Get the keys for the verifiers and the key value
                var valInputKey   = GetFinalHash(hashProvider, BlockKey_HashInput, baseHash);
                var valHashKey    = GetFinalHash(hashProvider, BlockKey_HashValue, baseHash);
                var valKeySizeKey = GetFinalHash(hashProvider, BlockKey_KeyValue, baseHash);

                //Decrypt
                encr.VerifierHashInput = DecryptAgileFromKey(encr, valInputKey, encr.EncryptedVerifierHashInput, encr.SaltSize, encr.SaltValue);
                encr.VerifierHash      = DecryptAgileFromKey(encr, valHashKey, encr.EncryptedVerifierHash, encr.HashSize, encr.SaltValue);
                encr.KeyValue          = DecryptAgileFromKey(encr, valKeySizeKey, encr.EncryptedKeyValue, encryptionInfo.KeyData.KeyBits / 8, encr.SaltValue);

                if (IsPasswordValid(hashProvider, encr))
                {
                    var ivhmac = GetFinalHash(hashProviderDataKey, BlockKey_HmacKey, encryptionInfo.KeyData.SaltValue);
                    var key    = DecryptAgileFromKey(encryptionInfo.KeyData, encr.KeyValue, encryptionInfo.DataIntegrity.EncryptedHmacKey, encryptionInfo.KeyData.HashSize, ivhmac);

                    ivhmac = GetFinalHash(hashProviderDataKey, BlockKey_HmacValue, encryptionInfo.KeyData.SaltValue);
                    var value = DecryptAgileFromKey(encryptionInfo.KeyData, encr.KeyValue, encryptionInfo.DataIntegrity.EncryptedHmacValue, encryptionInfo.KeyData.HashSize, ivhmac);

                    var hmca = GetHmacProvider(encryptionInfo.KeyData, key);
                    var v2   = hmca.ComputeHash(data);

                    for (int i = 0; i < v2.Length; i++)
                    {
                        if (value[i] != v2[i])
                        {
                            throw (new Exception("Dataintegrity key mismatch"));
                        }
                    }

                    int  pos     = 0;
                    uint segment = 0;

                    var doc = RecyclableMemory.GetStream();
                    while (pos < size)
                    {
                        var segmentSize = (int)(size - pos > 4096 ? 4096 : size - pos);
                        var bufferSize  = (int)(encryptedData.Length - pos > 4096 ? 4096 : encryptedData.Length - pos);
                        var ivTmp       = new byte[4 + encryptionInfo.KeyData.SaltSize];
                        Array.Copy(encryptionInfo.KeyData.SaltValue, 0, ivTmp, 0, encryptionInfo.KeyData.SaltSize);
                        Array.Copy(BitConverter.GetBytes(segment), 0, ivTmp, encryptionInfo.KeyData.SaltSize, 4);
                        var iv     = hashProviderDataKey.ComputeHash(ivTmp);
                        var buffer = new byte[bufferSize];
                        Array.Copy(encryptedData, pos, buffer, 0, bufferSize);

                        var b = DecryptAgileFromKey(encryptionInfo.KeyData, encr.KeyValue, buffer, segmentSize, iv);
                        doc.Write(b, 0, b.Length);
                        pos += segmentSize;
                        segment++;
                    }
                    doc.Flush();
                    return(doc);
                }
                else
                {
                    throw (new SecurityException("Invalid password"));
                }
            }
            return(null);
        }
示例#29
0
        public static bool WriteCentralDirectoryStructure(Stream s,
                                                          ICollection <ZipEntry> entries,
                                                          uint numSegments,
                                                          Zip64Option zip64,
                                                          String comment,
                                                          ZipContainer container)
        {
            var zss = s as ZipSegmentedStream;

            if (zss != null)
            {
                zss.ContiguousWrite = true;
            }

            // write to a memory stream in order to keep the
            // CDR contiguous
            Int64 aLength = 0;

            using (var ms = RecyclableMemory.GetStream())
            {
                foreach (ZipEntry e in entries)
                {
                    if (e.IncludedInMostRecentSave)
                    {
                        // this writes a ZipDirEntry corresponding to the ZipEntry
                        e.WriteCentralDirectoryEntry(ms);
                    }
                }
                var a = ms.ToArray();
                s.Write(a, 0, a.Length);
                aLength = a.Length;
            }


            // We need to keep track of the start and
            // Finish of the Central Directory Structure.

            // Cannot always use WriteStream.Length or Position; some streams do
            // not support these. (eg, ASP.NET Response.OutputStream) In those
            // cases we have a CountingStream.

            // Also, we cannot just set Start as s.Position bfore the write, and Finish
            // as s.Position after the write.  In a split zip, the write may actually
            // flip to the next segment.  In that case, Start will be zero.  But we
            // don't know that til after we know the size of the thing to write.  So the
            // answer is to compute the directory, then ask the ZipSegmentedStream which
            // segment that directory would fall in, it it were written.  Then, include
            // that data into the directory, and finally, write the directory to the
            // output stream.

            var  output = s as CountingStream;
            long Finish = (output != null) ? output.ComputedPosition : s.Position;  // BytesWritten
            long Start  = Finish - aLength;

            // need to know which segment the EOCD record starts in
            UInt32 startSegment = (zss != null)
                ? zss.CurrentSegment
                : 0;

            Int64 SizeOfCentralDirectory = Finish - Start;

            int countOfEntries = CountEntries(entries);

            bool needZip64CentralDirectory =
                zip64 == Zip64Option.Always ||
                countOfEntries >= 0xFFFF ||
                SizeOfCentralDirectory > 0xFFFFFFFF ||
                Start > 0xFFFFFFFF;

            byte[] a2 = null;

            // emit ZIP64 extensions as required
            if (needZip64CentralDirectory)
            {
                if (zip64 == Zip64Option.Never)
                {
#if NETCF || Core
                    throw new ZipException("The archive requires a ZIP64 Central Directory. Consider enabling ZIP64 extensions.");
#else
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(1);
                    if (sf.GetMethod().DeclaringType == typeof(ZipFile))
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipFile.UseZip64WhenSaving property.");
                    }
                    else
                    {
                        throw new ZipException("The archive requires a ZIP64 Central Directory. Consider setting the ZipOutputStream.EnableZip64 property.");
                    }
#endif
                }

                var a = GenZip64EndOfCentralDirectory(Start, Finish, countOfEntries, numSegments);
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
                if (startSegment != 0)
                {
                    UInt32 thisSegment = zss.ComputeSegment(a.Length + a2.Length);
                    int    i           = 16;
                    // number of this disk
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    // number of the disk with the start of the central directory
                    //Array.Copy(BitConverter.GetBytes(startSegment), 0, a, i, 4);
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);

                    i = 60;
                    // offset 60
                    // number of the disk with the start of the zip64 eocd
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                    i += 4;
                    i += 8;

                    // offset 72
                    // total number of disks
                    Array.Copy(BitConverter.GetBytes(thisSegment), 0, a, i, 4);
                }
                s.Write(a, 0, a.Length);
            }
            else
            {
                a2 = GenCentralDirectoryFooter(Start, Finish, zip64, countOfEntries, comment, container);
            }


            // now, the regular footer
            if (startSegment != 0)
            {
                // The assumption is the central directory is never split across
                // segment boundaries.

                UInt16 thisSegment = (UInt16)zss.ComputeSegment(a2.Length);
                int    i           = 4;
                // number of this disk
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
                // number of the disk with the start of the central directory
                //Array.Copy(BitConverter.GetBytes((UInt16)startSegment), 0, a2, i, 2);
                Array.Copy(BitConverter.GetBytes(thisSegment), 0, a2, i, 2);
                i += 2;
            }

            s.Write(a2, 0, a2.Length);

            // reset the contiguous write property if necessary
            if (zss != null)
            {
                zss.ContiguousWrite = false;
            }

            return(needZip64CentralDirectory);
        }
示例#30
0
        private MemoryStream EncryptPackageAgile(byte[] package, ExcelEncryption encryption)
        {
            var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n";

            xml += "<encryption xmlns=\"http://schemas.microsoft.com/office/2006/encryption\" xmlns:p=\"http://schemas.microsoft.com/office/2006/keyEncryptor/password\" xmlns:c=\"http://schemas.microsoft.com/office/2006/keyEncryptor/certificate\">";
            xml += "<keyData saltSize=\"16\" blockSize=\"16\" keyBits=\"256\" hashSize=\"64\" cipherAlgorithm=\"AES\" cipherChaining=\"ChainingModeCBC\" hashAlgorithm=\"SHA512\" saltValue=\"\"/>";
            xml += "<dataIntegrity encryptedHmacKey=\"\" encryptedHmacValue=\"\"/>";
            xml += "<keyEncryptors>";
            xml += "<keyEncryptor uri=\"http://schemas.microsoft.com/office/2006/keyEncryptor/password\">";
            xml += "<p:encryptedKey spinCount=\"100000\" saltSize=\"16\" blockSize=\"16\" keyBits=\"256\" hashSize=\"64\" cipherAlgorithm=\"AES\" cipherChaining=\"ChainingModeCBC\" hashAlgorithm=\"SHA512\" saltValue=\"\" encryptedVerifierHashInput=\"\" encryptedVerifierHashValue=\"\" encryptedKeyValue=\"\" />";
            xml += "</keyEncryptor></keyEncryptors></encryption>";

            var encryptionInfo = new EncryptionInfoAgile();

            encryptionInfo.ReadFromXml(xml);
            var encr = encryptionInfo.KeyEncryptors[0];
            var rnd  = RandomNumberGenerator.Create();

            var s = new byte[16];

            rnd.GetBytes(s);
            encryptionInfo.KeyData.SaltValue = s;

            rnd.GetBytes(s);
            encr.SaltValue = s;

            encr.KeyValue = new byte[encr.KeyBits / 8];
            rnd.GetBytes(encr.KeyValue);

            //Get the password key.
            var hashProvider = GetHashProvider(encryptionInfo.KeyEncryptors[0]);
            var baseHash     = GetPasswordHash(hashProvider, encr.SaltValue, encryption.Password, encr.SpinCount, encr.HashSize);
            var hashFinal    = GetFinalHash(hashProvider, BlockKey_KeyValue, baseHash);

            hashFinal = FixHashSize(hashFinal, encr.KeyBits / 8);

            var encrData = EncryptDataAgile(package, encryptionInfo, hashProvider);

            /**** Data Integrity ****/
            var saltHMAC = new byte[64];

            rnd.GetBytes(saltHMAC);

            SetHMAC(encryptionInfo, hashProvider, saltHMAC, encrData);

            /**** Verifier ****/
            encr.VerifierHashInput = new byte[16];
            rnd.GetBytes(encr.VerifierHashInput);

            encr.VerifierHash = hashProvider.ComputeHash(encr.VerifierHashInput);

            var VerifierInputKey = GetFinalHash(hashProvider, BlockKey_HashInput, baseHash);
            var VerifierHashKey  = GetFinalHash(hashProvider, BlockKey_HashValue, baseHash);
            var KeyValueKey      = GetFinalHash(hashProvider, BlockKey_KeyValue, baseHash);

            var ms = RecyclableMemory.GetStream();

            EncryptAgileFromKey(encr, VerifierInputKey, encr.VerifierHashInput, 0, encr.VerifierHashInput.Length, encr.SaltValue, ms);
            encr.EncryptedVerifierHashInput = ms.ToArray();
            ms.Dispose();

            ms = RecyclableMemory.GetStream();
            EncryptAgileFromKey(encr, VerifierHashKey, encr.VerifierHash, 0, encr.VerifierHash.Length, encr.SaltValue, ms);
            encr.EncryptedVerifierHash = ms.ToArray();
            ms.Dispose();

            ms = RecyclableMemory.GetStream();
            EncryptAgileFromKey(encr, KeyValueKey, encr.KeyValue, 0, encr.KeyValue.Length, encr.SaltValue, ms);
            encr.EncryptedKeyValue = ms.ToArray();
            ms.Dispose();

            xml = encryptionInfo.Xml.OuterXml;

            var byXml = Encoding.UTF8.GetBytes(xml);

            ms = RecyclableMemory.GetStream();
            ms.Write(BitConverter.GetBytes((ushort)4), 0, 2);  //Major Version
            ms.Write(BitConverter.GetBytes((ushort)4), 0, 2);  //Minor Version
            ms.Write(BitConverter.GetBytes((uint)0x40), 0, 4); //Reserved
            ms.Write(byXml, 0, byXml.Length);

            var doc = new CompoundDocument();

            //Add the dataspace streams
            CreateDataSpaces(doc);
            //EncryptionInfo...
            doc.Storage.DataStreams.Add("EncryptionInfo", ms.ToArray());
            ms.Dispose();

            //...and the encrypted package
            doc.Storage.DataStreams.Add("EncryptedPackage", encrData);

            ms = RecyclableMemory.GetStream();
            doc.Save(ms);
            //ms.Write(e,0,e.Length);
            return(ms);
        }