Ejemplo n.º 1
0
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="fi">The file</param>
        /// <param name="encryption"></param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(FileInfo fi, ExcelEncryption encryption)
        {
            MemoryStream ret = null;

            if (StgIsStorageFile(fi.FullName) == 0)
            {
                IStorage storage = null;
                if (StgOpenStorage(
                        fi.FullName,
                        null,
                        STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,
                        IntPtr.Zero,
                        0,
                        out storage) == 0)
                {
                    ret = GetStreamFromPackage(storage, encryption);
                    Marshal.ReleaseComObject(storage);
                }
            }
            else
            {
                throw(new InvalidDataException(string.Format("File {0} is not an encrypted package", fi.FullName)));
            }
            return(ret);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="stream">The memory stream. </param>
        /// <param name="encryption">The encryption object from the Package</param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(MemoryStream stream, ExcelEncryption encryption)
        {
            //Create the lockBytes object.
            ILockBytes lb = GetLockbyte(stream);

            MemoryStream ret = null;

            if (StgIsStorageILockBytes(lb) == 0)
            {
                IStorage storage = null;
                if (StgOpenStorageOnILockBytes(
                        lb,
                        null,
                        STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,
                        IntPtr.Zero,
                        0,
                        out storage) == 0)
                {
                    ret = GetStreamFromPackage(storage, encryption);
                }
                Marshal.ReleaseComObject(storage);
            }
            else
            {
                throw (new InvalidDataException("The stream is not an encrypted package"));
            }
            Marshal.ReleaseComObject(lb);

            return(ret);
        }
Ejemplo n.º 3
0
        public static WorkBook Load(string excelFilePath, string password)
        {
            FileInfo excelFile = new FileInfo(excelFilePath);

            ExceptionHelper.FalseThrow(excelFile.Exists, "文件不存在!");
            excelFile.Refresh();

            if (!string.IsNullOrEmpty(password))
            {
                EncryptedPackageHandler encrHandler    = new EncryptedPackageHandler();
                ExcelEncryption         fileEncryption = new ExcelEncryption();
                fileEncryption.IsEncrypted = true;
                fileEncryption.Password    = password;
                using (MemoryStream excelStream = encrHandler.DecryptPackage(excelFile, fileEncryption))
                {
                    return(Load(excelStream));
                }
            }
            else
            {
                using (FileStream stream = excelFile.OpenRead())
                {
                    return(Load(stream));
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 保存工作表为指定文件设置密码
        /// </summary>
        /// <param name="targetFilePath"></param>
        /// <param name="password"></param>
        public void Save(string targetFilePath, string password)
        {
            FileInfo targetFile = new FileInfo(targetFilePath);

            if (targetFile.Exists)
            {
                targetFile.Delete();
            }

            ExcelEncryption fileEncryption = new ExcelEncryption();

            fileEncryption.Password = password;

            if (fileEncryption.IsEncrypted)
            {
                using (FileStream fi = new FileStream(targetFile.FullName, FileMode.Create))
                {
                    byte[] file = this.SaveAsBytes();
                    EncryptedPackageHandler eph = new EncryptedPackageHandler();
                    using (MemoryStream ms = eph.EncryptPackage(file, fileEncryption))
                    {
                        fi.Write(ms.GetBuffer(), 0, (int)ms.Length);
                    }
                }
            }
            else
            {
                using (Package package = Package.Open(targetFile.FullName, FileMode.Create, FileAccess.ReadWrite))
                {
                    InnerSave(package);
                }
            }
        }
Ejemplo n.º 5
0
        private void EncryptPackageBinary(Stream package, ExcelEncryption encryption, Stream outputStream)
        {
            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(tempFolder);

            CreateDataSpaces(doc);

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

            //Encrypt the package
            byte[]       encryptedPackage = EncryptData(encryptionKey, package, false);
            MemoryStream ms = new MemoryStream();

            ms.Write(BitConverter.GetBytes((ulong)package.Length), 0, 8);
            ms.Write(encryptedPackage, 0, encryptedPackage.Length);
            doc.Storage.DataStreams.Add("EncryptedPackage", ms);

            doc.Save(outputStream);
        }
Ejemplo n.º 6
0
        //Helpmethod to output the streams in the storage
        //private void WriteDoc(CompoundDocument.StoragePart storagePart, string p)
        //{
        //    foreach (var store in storagePart.SubStorage)
        //    {
        //        string sdir=p + store.Key.Replace((char)6,'x') + "\\";
        //        Directory.CreateDirectory(sdir);
        //        WriteDoc(store.Value, sdir);
        //    }
        //    foreach (var str in storagePart.DataStreams)
        //    {
        //        File.WriteAllBytes(p + str.Key.Replace((char)6, 'x') + ".bin", str.Value);
        //    }
        //}
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="stream">The memory stream. </param>
        /// <param name="encryption">The encryption object from the Package</param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(MemoryStream stream, ExcelEncryption encryption)
        {
            //Create the lockBytes object.
            CompoundDocument.ILockBytes lb = null;
            try
            {
                lb = CompoundDocument.GetLockbyte(stream);

                if (CompoundDocument.IsStorageILockBytes(lb) == 0)
                {
                    var doc = new CompoundDocument(lb);
                    return(GetStreamFromPackage(doc, encryption));
                }
                else
                {
                    Marshal.ReleaseComObject(lb);
                    throw (new InvalidDataException("The stream is not an valid/supported encrypted document."));
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            finally
            {
                Marshal.ReleaseComObject(lb);
                lb = null;
            }
        }
Ejemplo n.º 7
0
        private MemoryStream GetStreamFromPackage(IStorage storage, ExcelEncryption encryption)
        {
            MemoryStream ret = null;

            comTypes.STATSTG statstg;

            storage.Stat(out statstg, (uint)STATFLAG.STATFLAG_DEFAULT);

            IEnumSTATSTG pIEnumStatStg = null;

            storage.EnumElements(0, IntPtr.Zero, 0, out pIEnumStatStg);

            comTypes.STATSTG[] regelt = { statstg };
            uint fetched = 0;
            uint res     = pIEnumStatStg.Next(1, regelt, out fetched);

            //if (regelt[0].pwcsName == "DataSpaces")
            //{
            //    PrintStorage(storage, regelt[0],"");
            //}
            if (res == 0)
            {
                byte[]         data;
                EncryptionInfo encryptionInfo = null;
                while (res != 1)
                {
                    switch (statstg.pwcsName)
                    {
                    case "EncryptionInfo":
                        data = GetOleStream(storage, statstg);
                        //File.WriteAllBytes(@"c:\temp\EncInfo1.bin", data);
                        encryptionInfo = new EncryptionInfo();
                        encryptionInfo.ReadBinary(data);

                        encryption.Algorithm = encryptionInfo.Header.AlgID == AlgorithmID.AES128 ?
                                               EncryptionAlgorithm.AES128 :
                                               encryptionInfo.Header.AlgID == AlgorithmID.AES192 ?
                                               EncryptionAlgorithm.AES192 :
                                               EncryptionAlgorithm.AES256;
                        break;

                    case "EncryptedPackage":
                        data = GetOleStream(storage, statstg);
                        ret  = DecryptDocument(data, encryptionInfo, encryption.Password);
                        break;
                    }

                    if ((res = pIEnumStatStg.Next(1, regelt, out fetched)) != 1)
                    {
                        statstg = regelt[0];
                    }
                }
            }
            Marshal.ReleaseComObject(pIEnumStatStg);
            return(ret);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Encrypts a package
 /// </summary>
 /// <param name="package">The package as a byte array</param>
 /// <param name="encryption">The encryption info from the workbook</param>
 /// <returns></returns>
 internal MemoryStream EncryptPackage(byte[] package, ExcelEncryption encryption)
 {
     if (encryption.Version == EncryptionVersion.Standard) //Standard encryption
     {
         return(EncryptPackageBinary(package, encryption));
     }
     else if (encryption.Version == EncryptionVersion.Agile) //Agile encryption
     {
         return(EncryptPackageAgile(package, encryption));
     }
     throw(new ArgumentException("Unsupported encryption version."));
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Encrypts a package
 /// </summary>
 /// <param name="package">The package as a byte array</param>
 /// <param name="encryption">The encryption info from the workbook</param>
 /// <returns></returns>
 internal void EncryptPackage(Stream package, ExcelEncryption encryption, Stream outputStream)
 {
     if (encryption.Version == EncryptionVersion.Standard) //Standard encryption
     {
         EncryptPackageBinary(package, encryption, outputStream);
         return;
     }
     else if (encryption.Version == EncryptionVersion.Agile) //Agile encryption
     {
         EncryptPackageAgile(package, encryption, outputStream);
         return;
     }
     throw (new ArgumentException("Unsupported encryption version."));
 }
Ejemplo n.º 10
0
        private MemoryStream GetStreamFromPackage(CompoundDocument doc, ExcelEncryption encryption)
        {
            if (doc.Storage.DataStreams.ContainsKey("EncryptionInfo") ||
                doc.Storage.DataStreams.ContainsKey("EncryptedPackage"))
            {
                var encryptionInfo = EncryptionInfo.ReadBinary(doc.Storage.DataStreams["EncryptionInfo"]);

                return(DecryptDocument(doc.Storage.DataStreams["EncryptedPackage"], encryptionInfo, encryption.Password));
            }
            else
            {
                throw (new InvalidDataException("Invalid document. EncryptionInfo or EncryptedPackage stream is missing"));
            }
        }
Ejemplo n.º 11
0
        private void GetStreamFromPackage(CompoundDocument doc, ExcelEncryption encryption, Stream outputStream)
        {
            if (doc.Storage.DataStreams.ContainsKey("EncryptionInfo") ||
                doc.Storage.DataStreams.ContainsKey("EncryptedPackage"))
            {
                var encryptionInfo = EncryptionInfo.ReadFile(doc.Storage.DataStreams["EncryptionInfo"] as FileStream);

                DecryptDocument(doc.Storage.DataStreams["EncryptedPackage"] as FileStream, encryptionInfo, encryption.Password, outputStream);
            }
            else
            {
                throw (new InvalidDataException("Invalid document. EncryptionInfo or EncryptedPackage stream is missing"));
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Read the package from the OLE document and decrypt it using the supplied password
 /// </summary>
 /// <param name="fi">The file</param>
 /// <param name="encryption"></param>
 /// <returns></returns>
 internal MemoryStream DecryptPackage(FileInfo fi, ExcelEncryption encryption)
 {
     CompoundDocument doc = new CompoundDocument(fi);
     
     MemoryStream ret = null;
     if (CompoundDocument.IsStorageFile(fi.FullName) == 0)
     {
         ret = GetStreamFromPackage(doc, encryption);
     }
     else
     {
         throw (new InvalidDataException(string.Format("File {0} is not an encrypted package", fi.FullName)));
     }
     return ret;
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="fi">The file</param>
        /// <param name="encryption"></param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(FileInfo fi, ExcelEncryption encryption)
        {
            if (CompoundDocument.IsCompoundDocument(fi))
            {
                CompoundDocument doc = new CompoundDocument(fi);

                MemoryStream ret = null;
                ret = GetStreamFromPackage(doc, encryption);
                return(ret);
            }
            else
            {
                throw (new InvalidDataException(string.Format("File {0} is not an encrypted package", fi.FullName)));
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="fi">The file</param>
        /// <param name="encryption"></param>
        /// <returns></returns>
        internal void DecryptPackage(FileInfo fi, ExcelEncryption encryption, Stream outputStream)
        {
            if (CompoundDocument.IsCompoundDocument(fi))
            {
                CompoundDocument doc = new CompoundDocument(fi, this.tempFolder);

                //Stream ret = null;
                GetStreamFromPackage(doc, encryption, outputStream);
            }
            else
            {
                throw (new InvalidDataException(string.Format("File {0} is not an encrypted package", fi.FullName)));
            }
            //return ret;
        }
Ejemplo n.º 15
0
 //Helpmethod to output the streams in the storage
 //private void WriteDoc(CompoundDocument.StoragePart storagePart, string p)
 //{
 //    foreach (var store in storagePart.SubStorage)
 //    {
 //        string sdir=p + store.Key.Replace((char)6,'x') + "\\";
 //        Directory.CreateDirectory(sdir);
 //        WriteDoc(store.Value, sdir);
 //    }
 //    foreach (var str in storagePart.DataStreams)
 //    {
 //        File.WriteAllBytes(p + str.Key.Replace((char)6, 'x') + ".bin", str.Value);
 //    }
 //}
 /// <summary>
 /// Read the package from the OLE document and decrypt it using the supplied password
 /// </summary>
 /// <param name="stream">The memory stream. </param>
 /// <param name="encryption">The encryption object from the Package</param>
 /// <returns></returns>
 internal void DecryptPackage(MemoryStream stream, ExcelEncryption encryption, Stream outputStream)
 {
     try
     {
         if (CompoundDocument.IsCompoundDocument(stream))
         {
             var doc = new CompoundDocument(stream, this.tempFolder);
             GetStreamFromPackage(doc, encryption, outputStream);
         }
         else
         {
             throw (new InvalidDataException("The stream is not an valid/supported encrypted document."));
         }
     }
     catch// (Exception ex)
     {
         throw;
     }
 }
Ejemplo n.º 16
0
 //Helpmethod to output the streams in the storage
 //private void WriteDoc(CompoundDocument.StoragePart storagePart, string p)
 //{
 //    foreach (var store in storagePart.SubStorage)
 //    {
 //        string sdir=p + store.Key.Replace((char)6,'x') + "\\";
 //        Directory.CreateDirectory(sdir);
 //        WriteDoc(store.Value, sdir);
 //    }
 //    foreach (var str in storagePart.DataStreams)
 //    {
 //        File.WriteAllBytes(p + str.Key.Replace((char)6, 'x') + ".bin", str.Value);
 //    }
 //}
 /// <summary>
 /// Read the package from the OLE document and decrypt it using the supplied password
 /// </summary>
 /// <param name="stream">The memory stream. </param>
 /// <param name="encryption">The encryption object from the Package</param>
 /// <returns></returns>
 internal MemoryStream DecryptPackage(MemoryStream stream, ExcelEncryption encryption)
 {
     try
     {
         if (CompoundDocument.IsCompoundDocument(stream))
         {
             var doc = new CompoundDocument(stream);
             return(GetStreamFromPackage(doc, encryption));
         }
         else
         {
             throw (new InvalidDataException("The stream is not an valid/supported encrypted document."));
         }
     }
     catch// (Exception ex)
     {
         throw;
     }
 }
Ejemplo n.º 17
0
        public void Save(Stream targetStream, string password)
        {
            ExcelEncryption fileEncryption = new ExcelEncryption();

            fileEncryption.Password = password;

            if (fileEncryption.IsEncrypted)
            {
                EncryptedPackageHandler eph = new EncryptedPackageHandler();
                using (MemoryStream encryptStream = eph.EncryptPackage(SaveAsBytes(), fileEncryption))
                {
                    encryptStream.Seek(0, SeekOrigin.Begin);
                    encryptStream.CopyTo(targetStream);
                    //ExcelHelper.CopyStream(encryptStream, targetStream);
                }
            }
            else
            {
                Save(targetStream);
            }
        }
Ejemplo n.º 18
0
 public static WorkBook Load(Stream input, string password)
 {
     if (!string.IsNullOrEmpty(password))
     {
         EncryptedPackageHandler encrHandler    = new EncryptedPackageHandler();
         ExcelEncryption         fileEncryption = new ExcelEncryption();
         fileEncryption.IsEncrypted = true;
         fileEncryption.Password    = password;
         using (MemoryStream copyStream = new MemoryStream())
         {
             input.CopyTo(copyStream);
             //ExcelHelper.CopyStream(input, copyStream);
             MemoryStream decrytStrem = encrHandler.DecryptPackage(copyStream, fileEncryption);
             return(Load(decrytStrem));
         }
     }
     else
     {
         return(null);
     }
 }
Ejemplo n.º 19
0
        /// <summary>
        /// 加密后Excel文件
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public byte[] SaveAsBytes(string password)
        {
            byte[]          byRet          = null;
            ExcelEncryption fileEncryption = new ExcelEncryption();

            fileEncryption.Password = password;
            if (fileEncryption.IsEncrypted)
            {
                EncryptedPackageHandler eph = new EncryptedPackageHandler();
                using (MemoryStream encryptStream = eph.EncryptPackage(SaveAsBytes(), fileEncryption))
                {
                    byRet = encryptStream.ToArray();
                }
            }
            else
            {
                byRet = SaveAsBytes();
            }

            return(byRet);
        }
Ejemplo n.º 20
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);
        }
Ejemplo n.º 21
0
        //Helpmethod to output the streams in the storage
        //private void WriteDoc(CompoundDocument.StoragePart storagePart, string p)
        //{
        //    foreach (var store in storagePart.SubStorage)
        //    {
        //        string sdir=p + store.Key.Replace((char)6,'x') + "\\";
        //        Directory.CreateDirectory(sdir);
        //        WriteDoc(store.Value, sdir);
        //    }
        //    foreach (var str in storagePart.DataStreams)
        //    {
        //        File.WriteAllBytes(p + str.Key.Replace((char)6, 'x') + ".bin", str.Value);
        //    }
        //}
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="stream">The memory stream. </param>
        /// <param name="encryption">The encryption object from the Package</param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(MemoryStream stream, ExcelEncryption encryption)
        {
            //Create the lockBytes object.
            CompoundDocument.ILockBytes lb=null;
            try
            {
                lb = CompoundDocument.GetLockbyte(stream);

                if (CompoundDocument.IsStorageILockBytes(lb) == 0)
                {
                    var doc = new CompoundDocument(lb);
                    return GetStreamFromPackage(doc, encryption);
                }
                else
                {
                    Marshal.ReleaseComObject(lb);
                    throw (new InvalidDataException("The stream is not an valid/supported encrypted document."));
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            finally
            {
                Marshal.ReleaseComObject(lb);
                lb = null;
            }
        }
Ejemplo n.º 22
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 passwork key.
            var hashProvider = GetHashProvider(encryptionInfo.KeyEncryptors[0]);
            var baseHash     = GetPasswordHash(hashProvider, encr.SaltValue, encryption.Password, encr.SpinCount, encr.HashSize);
            var hashFinal    = GetFinalHash(hashProvider, encr, 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, encr, BlockKey_HashInput, baseHash);
            var VerifierHashKey  = GetFinalHash(hashProvider, encr, BlockKey_HashValue, baseHash);
            var KeyValueKey      = GetFinalHash(hashProvider, encr, BlockKey_KeyValue, baseHash);

            var ms = new MemoryStream();

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

            ms = new MemoryStream();
            EncryptAgileFromKey(encr, VerifierHashKey, encr.VerifierHash, 0, encr.VerifierHash.Length, encr.SaltValue, ms);
            encr.EncryptedVerifierHash = ms.ToArray();

            ms = new MemoryStream();
            EncryptAgileFromKey(encr, KeyValueKey, encr.KeyValue, 0, encr.KeyValue.Length, encr.SaltValue, ms);
            encr.EncryptedKeyValue = ms.ToArray();

            xml = encryptionInfo.Xml.OuterXml;

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

            ms = new MemoryStream();
            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());
            //...and the encrypted package
            doc.Storage.DataStreams.Add("EncryptedPackage", encrData);

            ms = new MemoryStream();
            var e = doc.Save();

            ms.Write(e, 0, e.Length);
            return(ms);
        }
        private MemoryStream GetStreamFromPackage(IStorage storage, ExcelEncryption encryption)
        {
            MemoryStream ret=null;        
            comTypes.STATSTG statstg;
            
            storage.Stat(out statstg, (uint)STATFLAG.STATFLAG_DEFAULT);

            IEnumSTATSTG pIEnumStatStg = null;
            storage.EnumElements(0, IntPtr.Zero, 0, out pIEnumStatStg);

            comTypes.STATSTG[] regelt = { statstg };
            uint fetched = 0;
            uint res = pIEnumStatStg.Next(1, regelt, out fetched);

            //if (regelt[0].pwcsName == "DataSpaces")
            //{
            //    PrintStorage(storage, regelt[0],"");
            //}
            if (res == 0)
            {
                byte[] data;
                EncryptionInfo encryptionInfo = null;
                while (res != 1)
                {
                    switch (statstg.pwcsName)
                    {
                        case "EncryptionInfo":
                            data = GetOleStream(storage, statstg);
                            //File.WriteAllBytes(@"c:\temp\EncInfo1.bin", data);
                            encryptionInfo = new EncryptionInfo();
                            encryptionInfo.ReadBinary(data);

                            encryption.Algorithm = encryptionInfo.Header.AlgID == AlgorithmID.AES128 ? 
                                EncryptionAlgorithm.AES128 :
                            encryptionInfo.Header.AlgID == AlgorithmID.AES192 ? 
                                EncryptionAlgorithm.AES192 : 
                                EncryptionAlgorithm.AES256;
                            break;
                        case "EncryptedPackage":
                            data = GetOleStream(storage, statstg);
                            ret = DecryptDocument(data, encryptionInfo, encryption.Password);
                            break;
                    }

                    if ((res = pIEnumStatStg.Next(1, regelt, out fetched)) != 1)
                    {
                        statstg = regelt[0];
                    }
                }
            }
            Marshal.ReleaseComObject(pIEnumStatStg);
            return ret;
        }
        /// <summary>
        /// Encrypts a package
        /// </summary>
        /// <param name="package">The package as a byte array</param>
        /// <param name="encryption">The encryption info from the workbook</param>
        /// <returns></returns>
        internal MemoryStream EncryptPackage(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;

            //Create the document in-memory
            if (StgCreateDocfileOnILockBytes(lb,
                    STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE | STGM.TRANSACTED, 
                    0,
                    out storage)==0)
            {
                //First create the dataspace storage
                CreateDataSpaces(storage);

                //Create the Encryption info Stream
                comTypes.IStream stream;
                storage.CreateStream("EncryptionInfo", (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), (uint)0, (uint)0, out stream);
                byte[] ei=encryptionInfo.WriteBinary();
                stream.Write(ei, ei.Length, IntPtr.Zero);
                stream = null;

                //Encrypt the package
                byte[] encryptedPackage=EncryptData(encryptionKey, package, false);

                storage.CreateStream("EncryptedPackage", (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), (uint)0, (uint)0, out stream);

                //Write Size here
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write((ulong)package.LongLength);
                bw.Flush();
                byte[] length = ms.ToArray();
                //Write Encrypted data length first as an unsigned long
                stream.Write(length, length.Length, IntPtr.Zero);
                //And now the Encrypted data
                stream.Write(encryptedPackage, encryptedPackage.Length, IntPtr.Zero);
                stream = null;
                storage.Commit(0);
                lb.Flush();

                //Now copy the unmanaged stream to a byte array --> memory stream
                var statstg = new comTypes.STATSTG();
                lb.Stat(out statstg, 0);
                int size = (int)statstg.cbSize;
                IntPtr buffer = Marshal.AllocHGlobal(size);
                UIntPtr readSize;
                byte[] pack=new byte[size];
                lb.ReadAt(0, buffer, size, out readSize);
                Marshal.Copy(buffer, pack, 0, size);
                Marshal.FreeHGlobal(buffer);

                ret = new MemoryStream();
                ret.Write(pack, 0, size);
            }
            Marshal.ReleaseComObject(storage);
            Marshal.ReleaseComObject(lb);
            return ret;
        }
        /// <summary>
        /// Read the package from the OLE document and decrypt it using the supplied password
        /// </summary>
        /// <param name="stream">The memory stream. </param>
        /// <param name="encryption">The encryption object from the Package</param>
        /// <returns></returns>
        internal MemoryStream DecryptPackage(MemoryStream stream, ExcelEncryption encryption)
        {
            //Create the lockBytes object.
            ILockBytes lb = GetLockbyte(stream);

            MemoryStream ret = null;

            if (StgIsStorageILockBytes(lb) == 0)
            {
                IStorage storage = null;
                if (StgOpenStorageOnILockBytes(
                        lb,
                        null,
                        STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,
                        IntPtr.Zero,
                        0,
                        out storage) == 0)
                {
                    ret = GetStreamFromPackage(storage, encryption);
                }
                Marshal.ReleaseComObject(storage);
            }
            else
            {
                throw (new InvalidDataException("The stream is not an encrypted package"));
            }
            Marshal.ReleaseComObject(lb);

            return ret;
        }
 /// <summary>
 /// Read the package from the OLE document and decrypt it using the supplied password
 /// </summary>
 /// <param name="fi">The file</param>
 /// <param name="encryption"></param>
 /// <returns></returns>
 internal MemoryStream DecryptPackage(FileInfo fi, ExcelEncryption encryption)
 {
     MemoryStream ret = null;
     if (StgIsStorageFile(fi.FullName) == 0)
     {
         IStorage storage = null;
         if (StgOpenStorage(
             fi.FullName,
             null,
             STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,
             IntPtr.Zero,
             0,
             out storage) == 0)
         {
             ret = GetStreamFromPackage(storage, encryption);                    
             Marshal.ReleaseComObject(storage);
         }
     }
     else
     {
         throw(new InvalidDataException(string.Format("File {0} is not an encrypted package",fi.FullName)));
     }
     return ret;
 }
Ejemplo n.º 27
0
        private MemoryStream GetStreamFromPackage(CompoundDocument doc, ExcelEncryption encryption)
        {
            var ret = new MemoryStream();
            if(doc.Storage.DataStreams.ContainsKey("EncryptionInfo") ||
               doc.Storage.DataStreams.ContainsKey("EncryptedPackage"))
            {
                var encryptionInfo = EncryptionInfo.ReadBinary(doc.Storage.DataStreams["EncryptionInfo"]);

                return DecryptDocument(doc.Storage.DataStreams["EncryptedPackage"], encryptionInfo, encryption.Password);
            }
            else
            {
                throw (new InvalidDataException("Invalid document. EncryptionInfo or EncryptedPackage stream is missing"));
            }
        }
Ejemplo n.º 28
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);
            MemoryStream ms = new MemoryStream();
            ms.Write(BitConverter.GetBytes((ulong)package.LongLength), 0, 8);
            ms.Write(encryptedPackage, 0, encryptedPackage.Length);
            doc.Storage.DataStreams.Add("EncryptedPackage", ms.ToArray());

            var ret = new MemoryStream();
            var buffer = doc.Save();
            ret.Write(buffer, 0, buffer.Length);

            return ret;
        }
Ejemplo n.º 29
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 passwork key.
            var hashProvider = GetHashProvider(encryptionInfo.KeyEncryptors[0]);
            var baseHash = GetPasswordHash(hashProvider, encr.SaltValue, encryption.Password, encr.SpinCount, encr.HashSize);
            var hashFinal = GetFinalHash(hashProvider, encr, 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, encr, BlockKey_HashInput, baseHash);
            var VerifierHashKey = GetFinalHash(hashProvider, encr, BlockKey_HashValue, baseHash);
            var KeyValueKey = GetFinalHash(hashProvider, encr, BlockKey_KeyValue, baseHash);

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

            ms = new MemoryStream();
            EncryptAgileFromKey(encr, VerifierHashKey, encr.VerifierHash, 0, encr.VerifierHash.Length, encr.SaltValue, ms);
            encr.EncryptedVerifierHash = ms.ToArray();

            ms = new MemoryStream();
            EncryptAgileFromKey(encr, KeyValueKey, encr.KeyValue, 0, encr.KeyValue.Length, encr.SaltValue, ms);
            encr.EncryptedKeyValue = ms.ToArray();

            xml = encryptionInfo.Xml.OuterXml;

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

            ms = new MemoryStream();
            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());
            //...and the encrypted package
            doc.Storage.DataStreams.Add("EncryptedPackage", encrData);

            ms = new MemoryStream();
            var e=doc.Save();
            ms.Write(e,0,e.Length);
            return ms;
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Encrypts a package
 /// </summary>
 /// <param name="package">The package as a byte array</param>
 /// <param name="encryption">The encryption info from the workbook</param>
 /// <returns></returns>
 internal MemoryStream EncryptPackage(byte[] package, ExcelEncryption encryption)
 {
     if (encryption.Version == EncryptionVersion.Standard) //Standard encryption
     {
         return EncryptPackageBinary(package, encryption);
     }
     else if (encryption.Version == EncryptionVersion.Agile) //Agile encryption
     {
         return EncryptPackageAgile(package, encryption);
     }
     throw(new ArgumentException("Unsupported encryption version."));
 }
Ejemplo n.º 31
0
        /// <summary>
        /// Encrypts a package
        /// </summary>
        /// <param name="package">The package as a byte array</param>
        /// <param name="encryption">The encryption info from the workbook</param>
        /// <returns></returns>
        internal MemoryStream EncryptPackage(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;

            //Create the document in-memory
            if (StgCreateDocfileOnILockBytes(lb,
                                             STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE | STGM.TRANSACTED,
                                             0,
                                             out storage) == 0)
            {
                //First create the dataspace storage
                CreateDataSpaces(storage);

                //Create the Encryption info Stream
                comTypes.IStream stream;
                storage.CreateStream("EncryptionInfo", (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), (uint)0, (uint)0, out stream);
                byte[] ei = encryptionInfo.WriteBinary();
                stream.Write(ei, ei.Length, IntPtr.Zero);
                stream = null;

                //Encrypt the package
                byte[] encryptedPackage = EncryptData(encryptionKey, package, false);

                storage.CreateStream("EncryptedPackage", (uint)(STGM.CREATE | STGM.WRITE | STGM.DIRECT | STGM.SHARE_EXCLUSIVE), (uint)0, (uint)0, out stream);

                //Write Size here
                MemoryStream ms = new MemoryStream();
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write((ulong)package.LongLength);
                bw.Flush();
                byte[] length = ms.ToArray();
                //Write Encrypted data length first as an unsigned long
                stream.Write(length, length.Length, IntPtr.Zero);
                //And now the Encrypted data
                stream.Write(encryptedPackage, encryptedPackage.Length, IntPtr.Zero);
                stream = null;
                storage.Commit(0);
                lb.Flush();

                //Now copy the unmanaged stream to a byte array --> memory stream
                var statstg = new comTypes.STATSTG();
                lb.Stat(out statstg, 0);
                int     size   = (int)statstg.cbSize;
                IntPtr  buffer = Marshal.AllocHGlobal(size);
                UIntPtr readSize;
                byte[]  pack = new byte[size];
                lb.ReadAt(0, buffer, size, out readSize);
                Marshal.Copy(buffer, pack, 0, size);
                Marshal.FreeHGlobal(buffer);

                ret = new MemoryStream();
                ret.Write(pack, 0, size);
            }
            Marshal.ReleaseComObject(storage);
            Marshal.ReleaseComObject(lb);
            return(ret);
        }