/// <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; }
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")); } }
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; }
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 void CreateDataSpaces(CompoundDocument doc) { var ds = new CompoundDocument.StoragePart(); doc.Storage.SubStorage.Add("\x06" + "DataSpaces", ds); var ver=new CompoundDocument.StoragePart(); ds.DataStreams.Add("Version", CreateVersionStream()); ds.DataStreams.Add("DataSpaceMap", CreateDataSpaceMap()); var dsInfo=new CompoundDocument.StoragePart(); ds.SubStorage.Add("DataSpaceInfo", dsInfo); dsInfo.DataStreams.Add("StrongEncryptionDataSpace", CreateStrongEncryptionDataSpaceStream()); var transInfo=new CompoundDocument.StoragePart(); ds.SubStorage.Add("TransformInfo", transInfo); var strEncTrans=new CompoundDocument.StoragePart(); transInfo.SubStorage.Add("StrongEncryptionTransform", strEncTrans); strEncTrans.DataStreams.Add("\x06Primary", CreateTransformInfoPrimary()); }
//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; } }
internal void Save() { if (Validate()) { CompoundDocument doc = new CompoundDocument(); doc.Storage = new CompoundDocument.StoragePart(); var store = new CompoundDocument.StoragePart(); doc.Storage.SubStorage.Add("VBA", store); store.DataStreams.Add("_VBA_PROJECT", CreateVBAProjectStream()); store.DataStreams.Add("dir", CreateDirStream()); foreach (var module in Modules) { store.DataStreams.Add(module.Name, CompoundDocument.CompressPart(Encoding.GetEncoding(CodePage).GetBytes(module.Attributes.GetAttributeText() + module.Code))); } //Copy streams from the template, if used. if (Document != null) { foreach (var ss in Document.Storage.SubStorage) { if (ss.Key != "VBA") { doc.Storage.SubStorage.Add(ss.Key, ss.Value); } } foreach (var s in Document.Storage.DataStreams) { if (s.Key != "dir" && s.Key != "PROJECT" && s.Key != "PROJECTwm") { doc.Storage.DataStreams.Add(s.Key, s.Value); } } } doc.Storage.DataStreams.Add("PROJECT", CreateProjectStream()); doc.Storage.DataStreams.Add("PROJECTwm", CreateProjectwmStream()); if (Part == null) { Uri = new Uri(PartUri, UriKind.Relative); Part = _pck.CreatePart(Uri, ExcelPackage.schemaVBA); var rel = _wb.Part.CreateRelationship(Uri, TargetMode.Internal, schemaRelVba); } var vbaBuffer=doc.Save(); var st = Part.GetStream(FileMode.Create); st.Write(vbaBuffer, 0, vbaBuffer.Length); st.Flush(); st.Close(); //Save the digital signture Signature.Save(this); } }
private void GetProject() { var stream = Part.GetStream(); byte[] vba; vba = new byte[stream.Length]; stream.Read(vba, 0, (int)stream.Length); Document = new CompoundDocument(vba); ReadDirStream(); ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]); ReadModules(); ReadProjectProperties(); }
private void GetProject() { var stream = Part.GetStream(); byte[] vba; vba = new byte[stream.Length]; stream.Read(vba, 0, (int)stream.Length); Document = new CompoundDocument(vba); ReadDirStream(); ProjectStreamText = Encoding.GetEncoding(CodePage).GetString(Document.Storage.DataStreams["PROJECT"]); ReadModules(); ReadProjectProperties(); //foreach (var key in Document.Storage.SubStorage.Keys) //{ // if (key != "VBA") // { // var st = Document.Storage.SubStorage[key]; // VBFrame = Encoding.GetEncoding(CodePage).GetString(st.DataStreams["\x3VBFrame"]); // } //} }