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()); }
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()); } }
/// <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()); } } }
/// <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)); }
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()); } }
//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)); } } }
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()); } }
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); }
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); } } } }
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()); } }
// 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(); }
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); }
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]); } }
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); } }
/** 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()); } }
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); }
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()); } }
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()); } }
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; } } }
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); }
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()); } }
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()); } }
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); }
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(); }
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()); } }
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(); } } }
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); }
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); }
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); }