private unsafe void WriteIntegrityTable() { _file.Position = Header.IntegrityTable.OffsetInWim; foreach (XElement range in XmlEsdMetadata.Descendants("RANGE")) { int rangeLength = int.Parse(range.Attribute("Bytes").Value); long rangeOffset = long.Parse(range.Attribute("Offset").Value); long chunkStart = rangeOffset - sizeof(WimHeader); long chunkStartNum = chunkStart / IntegrityTable.Header.ChunkSize; long chunkEnd = rangeOffset + rangeLength - sizeof(WimHeader); long chunkEndNum = chunkEnd / IntegrityTable.Header.ChunkSize; using (SHA1 sha = SHA1.Create()) { for (long i = chunkStartNum; i <= chunkEndNum; i++) { _file.Position = sizeof(WimHeader) + i * IntegrityTable.Header.ChunkSize; int chunkSize = _file.Position + IntegrityTable.Header.ChunkSize > Header.XmlData.OffsetInWim ? (int)(Header.XmlData.OffsetInWim - _file.Position) : (int)IntegrityTable.Header.ChunkSize; byte[] data = _reader.ReadBytes(chunkSize); IntegrityTable.Hashes[i] = sha.ComputeHash(data, 0, data.Length); } } } _file.Position = Header.IntegrityTable.OffsetInWim; byte[] bItHeader = new byte[sizeof(IntegrityTableHeader)]; IntegrityTableHeader ith = IntegrityTable.Header; Marshal.Copy((IntPtr)(&ith), bItHeader, 0, bItHeader.Length); _writer.Write(bItHeader); foreach (byte[] b in IntegrityTable.Hashes) { _writer.Write(b); } }
public void DecryptEsd() { XmlEsdMetadata = XmlMetadata.Root?.Element("ESD"); if (XmlEsdMetadata == null) { throw new UnencryptedImageException(); } string b64AesKey = XmlEsdMetadata.Element("KEY")?.Value; if (string.IsNullOrEmpty(b64AesKey)) { throw new NoImageKeyException(); } byte[] bAesKey = Convert.FromBase64String(b64AesKey); bool success = false; foreach (byte[] cryptoKey in from k in CryptoKey.Keys orderby Math.Abs(k.FirstBuild - BuildNumber) select k.Key) { try { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.ImportCspBlob(cryptoKey); bAesKey = rsa.Decrypt(bAesKey, true); } } catch (CryptographicException) { continue; } success = true; break; } if (!success) { throw new NoValidCryptoKeyException(); } foreach (XElement range in XmlEsdMetadata.Descendants("RANGE")) { int rangeLength = int.Parse(range.Attribute("Bytes").Value); long rangeOffset = long.Parse(range.Attribute("Offset").Value); _file.Position = rangeOffset; int bEncryptedSize = (rangeLength / 16 + 1) * 16; byte[] bEncrypted = _reader.ReadBytes(bEncryptedSize); using (AesCryptoServiceProvider aesCipher = new AesCryptoServiceProvider { Key = bAesKey, IV = Convert.FromBase64String("AAAAAAAAAAAAAAAAAAAAAA=="), Mode = CipherMode.CBC, Padding = PaddingMode.None }) using (MemoryStream msEncrypted = new MemoryStream(bEncrypted)) using (CryptoStream strCrypto = new CryptoStream(msEncrypted, aesCipher.CreateDecryptor(), CryptoStreamMode.Read)) { byte[] bDecrypted = new byte[bEncryptedSize - 16]; strCrypto.Read(bDecrypted, 0, bDecrypted.Length); _file.Position = rangeOffset; _file.Write(bDecrypted, 0, bDecrypted.Length); _file.Flush(); } } XmlEsdMetadata.Remove(); WriteXmlMetadata(); WriteIntegrityTable(); WriteWimHeader(); }