基于测试某录播课平台视频安全性的需求, 对平台上的免费视频进行安全测试,看看到底能否较好的防下载。
以下为几种常用的视频加密技术,我们这次的测试平台采用的是第二种,第三种方式主要依靠专用播放器来解决数据交到客户端的这一环的安全性,但是专用播放器带来了使用不便的兼容问题。
1、防盗链技术:这种严格来说,不属于视频加密,只是想办法防止视频被下载,只允许在线播放。但这种基本上来说属于防一般用户,很容易被绕过去。因为你只要让浏览器可以播放,别人就可以伪装自己是浏览器,拿到url,进行伪装浏览器的各种referer等信息,欺骗过防盗链系统,下载到视频。
2、HLS加密技术:也可以称之为m3u8切片加密,这种是目前H5时代广泛使用的技术,该加密本身是很安全的,基于AES加密算法。但有个致命的问题:别人很容易拿到秘钥进行解密。这种方式最大的优点是:几乎主流浏览器都支持,包括微信、qq等,打开就能播放,兼容性很好。缺点也很明显:
因为算法是公开的,并且如果不保护好秘钥文件,ffmpeg等命令行、很多工具软件,均可拿到秘钥对视频基本还原,如果只是采用单纯的HLS加密技术,可以说:极其不安全。幸好,近几年国内很多厂商在标准HLS加密的基础上,对m3u8文件中的秘钥等做了防盗处理,这种二者结合,效果就好很多。
3、视频文件内容采用私有算法真正逐帧加密:这种方式一般是基于不公开的算法,对视频文件、直播流、m3u8中的ts数据等,均可实现实时逐帧加密。但加密后的视频,需要专用特定播放器才可以播放。由于采用私有算法,因此其他播放器无法进行播放,增强了安全性。但也带来了一定不便利性,就是必须安装专用软件。不过这类技术就比较考验加密实力了,目前很多加密软件号称加密,但某宝等平台随便一搜,也有很多破解。因为,即使你用了专用播放器,但如果别人很容易逆向你的播放器,也就知道了加密算法,所以需要开发公司有多年深厚的研发实力才可以放心。
https://www.zhihu.com/question/24561177/answer/1191234975
首先打开视频平台视频连接,打开浏览器调试窗口查看视频连接,可见是 EduSoho 气球云提供的播放方案,HLS 流媒体视频格式,使用 VLC 打开视频地址并不能直接播放,视频地址内容是加密的。
进一步查看 m3u8 文件内容可以看到,视频切片内容使用了 AES-128加密,解码需要 iv (偏移量),key (秘钥),m3u8 内 EXT-X-KEY,URL 记录了秘钥的获取路径,而打开此网址是需要 cookie 鉴定访问者身份的,且可以在平台后端控制用户的秘钥过期时间,到此为止,仍然还是安全。
接下来,进行进一步的测试,对于普通 HLS 格式视频,使用 ffmpeg 可以直接下载转为 mp4 格式,但是案例这种加密视频是不可以的,需要对下载下来的视频切片进行解码。
ffmpeg -i https://embed-fastly.wistia.com/deliveries/bde18e17ca5ff78ec940fc82c76ed6194f4f7886.m3u8 wistia.mp4
通过 m3u8 内获取到的 iv , 和秘钥尝试解码失败,说明 iv , key 秘钥保护变形过,并不能直接使用。
openssl aes-128-cbc -d -in fileSequence0.ts -out fileSequence0_decrypto.ts -nosalt -iv *** -K ***
秘钥已经下发给浏览器客户端,那么解密的工作一定是在浏览器内通过 Javascript 完成的,由于 Javascript 的透明性,这里的加密算法并不安全。
打开调试查看调用的 js 文件,可以看到有 气球云(EduSoho) 的播放器 SDK。
打开 js文件查看,是经过 webpack 打包过的,原文件的路径仍然可见,"/src/crypt/decrypter.js" 看起来就是解密算法所在。
定位到相关函数 ,可以看到是对秘钥进行过一系列的操作换出来的,对视频切片解码后操作 Dom 把播放内容推给播放器。
由于打包加密过的 js 代码,变量都被换过,调试起来非常困难,解读跟踪代码来获取解密算法的方式理论上可行,但是花费的时间很难预估,会让很多人知难而退,前端对秘钥的加密算法的目的基本也达到了。
继续进行下一步之前,我们注意到 气球云的播放器 SDK 的 js 文件未采用 https 加密传输,那也就意味着可以被劫持后 插入调试代码,破解将变得更加容易,如图,我们通过反向代理+hosts 文件修改的方式将目标 js 文件劫持到本地文件,插入调试代码。
现在最简单方式是直接获取解密后的切片内容,不理会解密过程。
从原代码可以看到视频内容的解密是在浏览器 ServiceWoker 内进行的, 这里并不能操作 dom 还不能很方便的将解密内容取出来。
可以看到,解密后 ServiceWoker 通过 postMessage 发解密内容给主进程,我们接下来只有 添加监听器截取对应时间和内容。
并将解密的内容放到全局变量内 window._files 。
t.onWorkerMessage = function(e) {
if (e.data.event=="hlsFragParsingData" && e.data.data.type == "pureData" ) {
var _files = window.files || {}
_files[e.data.data.sn] = e.data.data.data;
window.files = _files
console.log('sn', e.data.data.sn,Object.keys(_files).length, Math.round(Object.keys(_files).length/6)+" mins");
window.sn = e.data.data.sn
}
...
}
最后使用 window.saveAs('xx.ts') 下载合并后的视频文件。
window.saveAs = (filename) => {
var blob = Object.values(window._files)
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename)
} else {
const link = document.createElement('a')
const body = document.querySelector('body')
link.href = window.URL.createObjectURL(new Blob(blob, {type: "application/zip"}))\
link.download = filename
link.style.display = 'none'
body.appendChild(link)
link.click()
body.removeChild(link)
window.webkitURL.revokeObjectURL(link.href)
}
}
可以看到,虽然视频最终下载了,但是需要一点的前提条件 比如 http 不安全协议,逆向加密算法的时间成本等。
视频保护问题的根本是总有那么一个环节你要将视频真实数据交给客户端,这个环节是平台控制的更多还是客户自己控制的更多,决定了效果。 强如 DRM 数字版权保护的方案,设置了很多限制条件比如播放时必须在线、解码是在专用硬件是解密的,但是数据总要给显示器的,所以仍然存在 hdmi、wifi投屏 的盗录方式。
安全是相对的, 目前能做的只能是增加破解者的成本。
WebAssembly
WebAssembly
(缩写WASM)是一种安全,便携,低级代码设计用于高效执行和紧凑表示的格式。
它的主要目标是使Web上的高性能应用,不需要针对网络的特定假设或提供特定的定制化的网络功能,因此它可以在其他环境中直接使用,也就是良好的跨平台特性。 WebAssembly是由W3C社区组开发的开放标准
《WebAssembly 在性能及加密场景的深度探索》。
https://gmtc.infoq.cn/2019/shenzhen/presentation/2064?utm_source=infoq&utm_medium=arti&utm_campaign=8&utm_content=zhaoyang&utm_term=1108
WebAssembly在性能及加密场景的深度探索
https://cloud.tencent.com/developer/news/471800