private static byte[] EncryptPekList(byte[] cleartextBlob, PekListVersion pekListVersion, byte[] bootKey = null)
        {
            // Do not encrypt by default.
            PekListFlags flags = PekListFlags.Clear;

            if (bootKey != null)
            {
                // Encrypt if the boot key is provided.
                Validator.AssertLength(bootKey, BootKeyRetriever.BootKeyLength, "bootKey");
                flags = PekListFlags.Encrypted;
            }

            // Generate random salt
            byte[] salt = GenerateSalt(SaltSize);

            // Encode the data structure
            using (MemoryStream stream = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    // Header
                    writer.Write((uint)pekListVersion);
                    writer.Write((uint)flags);
                    writer.Write(salt);

                    // Data
                    switch (flags)
                    {
                    case PekListFlags.Clear:
                        writer.Write(cleartextBlob);
                        break;

                    case PekListFlags.Encrypted:
                        byte[] encryptedBlob;
                        switch (pekListVersion)
                        {
                        case PekListVersion.W2016:
                            encryptedBlob = EncryptUsingAES(cleartextBlob, salt, bootKey);
                            writer.Write(encryptedBlob);
                            // Add 16B zeroed padding. The purpose in unknown and NTDS even works without it.
                            byte[] padding = new byte[PekListV3PaddingSize];
                            writer.Write(padding);
                            break;

                        case PekListVersion.W2k:
                            encryptedBlob = EncryptUsingRC4(cleartextBlob, salt, bootKey, BootKeySaltHashRounds);
                            writer.Write(encryptedBlob);
                            break;

                        default:
                            // TODO: Extract as a resource.
                            throw new FormatException("Unsupported PEK list version.");
                        }
                        break;
                    }
                }

                return(stream.ToArray());
            }
        }
        private static byte[] EncryptPekList(byte[] cleartextBlob, PekListVersion pekListVersion, byte[] bootKey = null)
        {
            // Do not encrypt by default.
            PekListFlags flags = PekListFlags.Clear;

            if (bootKey != null)
            {
                // Encrypt if the boot key is provided.
                Validator.AssertLength(bootKey, BootKeyRetriever.BootKeyLength, "bootKey");
                flags = PekListFlags.Encrypted;
            }

            // Generate random salt
            byte[] salt = new byte[SaltSize];
            using (var rng = RandomNumberGenerator.Create())
            {
                rng.GetBytes(salt);
            }

            // Encode the data structure
            using (MemoryStream stream = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    // Header
                    writer.Write((uint)pekListVersion);
                    writer.Write((uint)flags);
                    writer.Write(salt);

                    // Data
                    switch (flags)
                    {
                    case PekListFlags.Clear:
                        writer.Write(cleartextBlob);
                        break;

                    case PekListFlags.Encrypted:
                        byte[] encryptedBlob;
                        switch (pekListVersion)
                        {
                        case PekListVersion.W2016:
                            encryptedBlob = EncryptUsingAES(cleartextBlob, salt, bootKey, PaddingMode.Zeros);
                            break;

                        case PekListVersion.W2k:
                            encryptedBlob = EncryptUsingRC4(cleartextBlob, salt, bootKey, BootKeySaltHashRounds);
                            break;

                        default:
                            // TODO: Extract as a resource.
                            throw new FormatException("Unsupported PEK list version.");
                        }
                        writer.Write(encryptedBlob);
                        break;
                    }
                }

                return(stream.ToArray());
            }
        }
        private static byte[] EncryptPekList(byte[] cleartextBlob, byte[] bootKey = null)
        {
            // Do not encrypt by default.
            PekListFlags flags = PekListFlags.Clear;

            if (bootKey != null)
            {
                // Encrypt if the boot key is provided.
                Validator.AssertLength(bootKey, BootKeyRetriever.BootKeyLength, "bootKey");
                flags = PekListFlags.Encrypted;
            }

            int bufferSize = EncryptedPekListOffset + cleartextBlob.Length;

            byte[] buffer = new byte[bufferSize];

            // Generate random salt
            byte[] salt = new byte[SaltSize];
            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(salt);
            }
            using (MemoryStream stream = new MemoryStream(buffer))
            {
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    // Header
                    // TODO: Write version corresponding to the DB or original version!!!
                    writer.Write((uint)PekListVersion.W2k);
                    writer.Write((uint)flags);
                    writer.Write(salt);
                    // Data
                    switch (flags)
                    {
                    case PekListFlags.Clear:
                        writer.Write(cleartextBlob);
                        break;

                    case PekListFlags.Encrypted:
                        byte[] encryptedBlob = EncryptUsingRC4(cleartextBlob, salt, bootKey, BootKeySaltHashRounds);
                        writer.Write(encryptedBlob);
                        break;
                    }
                }
            }
            return(buffer);
        }