Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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();
        }