Потоковое потоковое видео в зашифрованном виде (AES-CTR) с использованием веб-прокси (nanoHTTPD) - PullRequest
0 голосов
/ 25 мая 2019

У меня есть зашифрованное (128-AES-CTR-NoPadding) видео, находящееся на сервере, которое мне нужно расшифровать при загрузке, чтобы пользователь мог транслировать его (в обычных проигрывателях / в Интернете).

Я понимаю компоненты этого решения и то, как они должны быть соединены, чтобы сделать эту работу. Это частично работает, но в остальном я просто не могу правильно реализовать потоковую передачу. Я читал и учился на примерах (большинство из которых воспроизводит файл на диске, чего не происходит здесь) по этой теме на прошлой неделе, и пришел к выводу, что это вне меня, и мне нужна помощь.

Детали

Я использую облегченный веб-сервер ( nanoHttpd ), действующий как прокси-сервер для загрузки зашифрованных данных с удаленного сервера и обслуживания дешифрованных данных . Ниже приведены основные коды внутри моего метода NanoHTTPD.serve.

//create urlConnection to encrypted video file with proper headers (ie range headers) as request received by the proxy server
InputStream inputStream = new CipherInputStream(cipher, urlConnection.getInputStream());
return newChunkedResponse(status, contentType,inputStream);

Так что теперь, если я зайду на свой веб-сервер NanoHttpd (http://localhost:9000),, файл начнет загружаться, и после завершения загрузки файл полностью расшифровывается и воспроизводится, как и ожидалось. Таким образом, это гарантирует, что получение зашифрованных данных с сервера и обслуживание дешифрованных данных работает правильно. Но когда любой видеоплеер (html5, vlc) запрашивает потоковую передачу видео с этого URL, он просто не работает.

Если приведенный выше код в NanoHTTPD.serve изменился на

//create urlConnection to cleardata video file with proper headers (ie range headers) as request received by the proxy server
    InputStream inputStream = urlConnection.getInputStream();
    return newChunkedResponse(status, contentType,inputStream);

А потом попробуйте стримить с вышеупомянутых плееров, все будет работать нормально. Таким образом, это гарантирует, что веб-прокси корректирует получение и подачу данных.

Потенциальная проблема Для поддержки запросов диапазона от видеопроигрывателя нам нужно будет правильно пропустить границу блока, кратную размеру блока шифра. Таким образом, возможно, что когда видеопроигрыватель запрашивает данные с заголовком (диапазон: байты 34-44), CipherInputStream, вероятно, не может расшифровать данные, так как входной поток имеет данные от 34-44. Но я не знаю, как это сделать с помощью urlConnection.getInputStream () и CipherInputStream.

Но даже без этого он должен, по крайней мере, начать воспроизведение в первые несколько секунд, потому что первый запрос, который посылает видеопроигрыватель, равен (диапазон: 0-), что означает, что inputStream начинается с индекса 0, поэтому CipherInputStream должен быть в состоянии расшифровать и обработать эти начальные байты, и видео должно продолжаться.

Я в полной растерянности, потому что не знаю, как это отладить. Любые идеи, примеры кодов приветствуются, я опробую их и выложу результаты здесь.

1 Ответ

0 голосов
/ 28 мая 2019

Я должен понять это.Я опубликую решение здесь для других.

Проблема здесь заключалась в распределенных запросах.Если прокси-сервер не отправляет правильные ответы на эти запросы диапазона, воспроизведение не будет выполнено.Это может произойти сбой по ряду причин.

  1. В ваших запросах к удаленному серверу отсутствуют правильные заголовки диапазона.
  2. В ваших запросах к удаленному серверу возвращаются данные правильного ранжирования, но выне расшифровывает это правильно.Это был мой случай.Конечно, этот процесс расшифровки будет варьироваться от шифра к шифру.Для меня я использовал (AES / CRT / NOPADDING), я поставлял правильный iv для смещения.Как рассчитать iv для смещения, описано здесь .

Что касается примеров кода, мне пришлось добавить только одну строку перед

InputStream inputStream = new CipherInputStream(cipher, urlConnection.getInputStream());
return newChunkedResponse(status, contentType,inputStream);

, что

jumpToOffset(cipher,....);

После этого все работало правильно, включая поиск видео.

...