Прежде всего, неплохо зашифровать исходное видео по частям. Таким образом, зашифрованный видеофайл представляет собой набор зашифрованных частей. Просто разбейте оригинальный файл на части одинакового размера и зашифруйте их.
Здесь приведена схема (OutputStream - поток зашифрованного видеофайла, InputStream - исходный файловый поток, ChunkSize - размер каждой части в исходном файле, также мы записываем некоторые метаданные: размеры оригинальных и зашифрованных фрагментов):
using (BinaryWriter Writer = new BinaryWriter(OutputStream))
{
byte[] Buf = new byte[ChunkSize];
List<int> SourceChunkSizeList = new List<int>();
List<int> EncryptedChunkSizeList = new List<int>();
int ReadBytes;
while ((ReadBytes = InputStream.Read(Buf, 0, Buf.Length)) > 0)
{
byte[] EncryptedData = Encrypt(Buf, ReadBytes);
OutputStream.Write(EncryptedData, 0, EncryptedData.Length);
SourceChunkSizeList.Add(ReadBytes);
EncryptedChunkSizeList.Add(EncryptedData.Length);
}
foreach (int SourceChunkSize in SourceChunkSizeList)
Writer.Write(SourceChunkSize);
foreach (int EncryptedChunkSize in EncryptedChunkSizeList)
Writer.Write(EncryptedChunkSize);
}
Такие метаданные помогут быстро найти зашифрованную часть.
Во-вторых, не расшифровывайте зашифрованные данные в каждом запросе на чтение. Кэшируйте это: воспроизведение видео в большинстве случаев является просто последовательным чтением.
Сложная задача - воспроизвести зашифрованный видеофайл. Вы можете написать либо фильтр DirectShow (решение для видео), либо проверить сторонний продукт (многоцелевое решение): BoxedApp, SDK для виртуализации. Круто то, что у них есть статья, в которой показано, как точно решить вашу задачу, смотрите: http://boxedapp.com/encrypted_video_streaming.html