使用 Web 代理 (nanoHTTPD) 即时流式传输 [随机访问] 加密 (AES-CTR) 视频
Streaming [Random Access] encrypted (AES-CTR) video on the fly using web proxy (nanoHTTPD)
我有一个加密的 (128-AES-CTR-NoPadding) 视频驻留在服务器上,我需要在下载时对其进行解密,以便用户可以流式传输它(正常 players/web)。
我了解此解决方案的组成部分以及应如何将它们组合在一起以使其发挥作用。它部分有效,但对于其余部分,我无法正确实现流式传输。在过去的一周里,我一直在阅读和学习示例(其中大部分是在播放磁盘上的文件,这里不是这种情况),并得出结论这超出了我的范围,我需要一些帮助。
详情
我正在使用轻量级网络服务器 (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);
然后尝试从上述播放器进行流式传输,它会工作得很好。
因此,这可确保 Web 代理正确检索和提供数据。
潜在问题
为了支持来自视频播放器的范围请求,我们需要正确地跳到块边界,该块边界是密码块大小的倍数。因此,当视频播放器使用 header(范围:字节 34-44)请求数据时,CipherInputStream 可能无法解密数据,因为输入流具有来自 34-44 的数据。但是我不知道如何使用 urlConnection.getInputStream() 和 CipherInputStream.
但即使没有这个,它至少应该开始播放前几秒,因为视频播放器发送的第一个请求是(范围:0-),这意味着 inputStream 从index 0 因此 CipherInputStream 应该能够解密并提供这些初始字节并且视频应该继续播放。
我完全不知所措,因为我不知道如何调试它。欢迎任何想法和示例代码,我将尝试它们并在此处 post 结果。
我已经弄明白了。我会 post 在这里为其他人提供解决方案。
这里的问题是远程请求。如果代理没有对这些范围请求发送正确的响应,播放将失败。由于多种原因,这可能会失败。
- 您对远程服务器的请求缺少正确的范围 headers。
- 您对远程服务器的请求返回了正确的范围数据,但您没有正确解密。这是我的情况。当然,这个解密过程会因密码而异。对我来说,我使用了 (AES/CRT/NOPADDING),我为偏移量提供了正确的 iv。 here.
描述了如何计算偏移量的 iv
就代码示例而言,我只需要在前面添加一行
InputStream inputStream = new CipherInputStream(cipher, urlConnection.getInputStream());
return newChunkedResponse(status, contentType,inputStream);
这是
jumpToOffset(cipher,....);
之后一切正常,包括寻找视频。
我有一个加密的 (128-AES-CTR-NoPadding) 视频驻留在服务器上,我需要在下载时对其进行解密,以便用户可以流式传输它(正常 players/web)。
我了解此解决方案的组成部分以及应如何将它们组合在一起以使其发挥作用。它部分有效,但对于其余部分,我无法正确实现流式传输。在过去的一周里,我一直在阅读和学习示例(其中大部分是在播放磁盘上的文件,这里不是这种情况),并得出结论这超出了我的范围,我需要一些帮助。
详情
我正在使用轻量级网络服务器 (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);
然后尝试从上述播放器进行流式传输,它会工作得很好。 因此,这可确保 Web 代理正确检索和提供数据。
潜在问题 为了支持来自视频播放器的范围请求,我们需要正确地跳到块边界,该块边界是密码块大小的倍数。因此,当视频播放器使用 header(范围:字节 34-44)请求数据时,CipherInputStream 可能无法解密数据,因为输入流具有来自 34-44 的数据。但是我不知道如何使用 urlConnection.getInputStream() 和 CipherInputStream.
但即使没有这个,它至少应该开始播放前几秒,因为视频播放器发送的第一个请求是(范围:0-),这意味着 inputStream 从index 0 因此 CipherInputStream 应该能够解密并提供这些初始字节并且视频应该继续播放。
我完全不知所措,因为我不知道如何调试它。欢迎任何想法和示例代码,我将尝试它们并在此处 post 结果。
我已经弄明白了。我会 post 在这里为其他人提供解决方案。
这里的问题是远程请求。如果代理没有对这些范围请求发送正确的响应,播放将失败。由于多种原因,这可能会失败。
- 您对远程服务器的请求缺少正确的范围 headers。
- 您对远程服务器的请求返回了正确的范围数据,但您没有正确解密。这是我的情况。当然,这个解密过程会因密码而异。对我来说,我使用了 (AES/CRT/NOPADDING),我为偏移量提供了正确的 iv。 here. 描述了如何计算偏移量的 iv
就代码示例而言,我只需要在前面添加一行
InputStream inputStream = new CipherInputStream(cipher, urlConnection.getInputStream());
return newChunkedResponse(status, contentType,inputStream);
这是
jumpToOffset(cipher,....);
之后一切正常,包括寻找视频。