前端于我
前端 / video / 视频加密

国内视频站点加密方式探究与破解

由于最近在研究视频这块的,所以对于视频加密方式也就理所当然的研究了一番。

目前常见的视频加密手段

总的来说,目前不管是web端还是native端。视频的加密看起来都大同小异,主要有以下几种:

  1. DRM加密:

DRM英文全称Digital Rights Management, 可以翻译为:数字版权管理。目前市面上常见的DRM分别有谷歌的widewine, 苹果的fairPlay, 微软的(???微软的啥来着,一下想不起来了),这几家巨头在实现自家的DRM加密模块的同时,也将DRM的环境割裂开来,像苹果就仅仅支持自家的fairPlay加密,比如在Safari里你就只能用fairPlay,而在Chrome里就只能用widewine,而DRM加解密通常又会分好几种登记,比如支持在硬件层面的加解密与只能在软件层面的加解密两者的安全登记根本就不一样。

而DRM相对来说是目前视频加密这块最安全的一种加密方式,当然如果真的有更牛逼的大佬能写出更加难破解的那就只能膜拜了,反正目前从网上资料看起来,似乎DRM仍然没人破解,虽然有一些破解了widewine的l3级别的加密的流言(也就是软件层面的加密,类似chrome浏览器内的DRM模块),但是没有实锤,所以暂不可信。

虽说它的安全性最高,但是实现起来还是很麻烦的,目前看到国内似乎也就那几个大型的视频站点用上了DRM,而且也不是全部视频都是用DRM,只有一小部分精选的,或者供应商要求的(比如好莱坞大片),其他的基本上也不会给你上DRM加密,所以也就导致国内关于这部分的资料少之又少。

  1. 基于HLS的AES加密:

目前网页上的HLS格式视频占了视频总量的50%以上,所以基于HLS的AES加密的使用也算是比较多的,使用起来也很方便,(video.js已经有配套的插件可以直接使用)。但是这个加密缺点也很明显,那就是不安全,因为一般来说解密的key地址都是直接写在m3u8文件上,所以也就导致了别人要拿到解密key几乎没有成本,当然你也可以不写在m3u8文件上,而是通过在代码里自己获取,但是这无异于脱了裤子放屁,由于前端的不安全性,对于有点调试能力的人来说,也是很不安全的。

  1. 自研加密算法:

自研加密算法在国内目前的视频领域应该还是比较常见的,通常不过是在视频封装上加入一些噪音,在解封装的时候通过特定的key索引移除这类噪音,得到可播放的视频数据。这类加密算法简单来说还是算比使用通用的AES视频加密要难一些,但是也非常有限,及时你将解密key隐藏的再完美,将加解密写的再复杂,破解起来也不会特别困难。这里留个悬念,后面再细说这类是如何破解的。

  1. 连接鉴权,防盗链:

这个严格上来说已经不算是视频加密了,但是他也起到了防止别人盗取视频的作用,所以这里也就简单拿出来讲一下。其实这很好理解,也就是在播放的时候鉴权,是否提供视频,这是最简单的一种防盗技术,实现门槛也很低,所以也就很多人用。就像我们伟大领袖邓主席说的,不管黑猫白猫,能抓到老鼠的就是好猫。

暂时整理到这里,这样一看,视频加密这块还真是单调,唯一安全一点的也就是使用DRM了。但是即使是DRM也不能抵挡偷盗者的无耻–直接录屏将内容录下来。

如何防翻录

说到视频加密防盗,防翻录是迈不过去的一道坎。无论你使用怎样的加密,在愿意牺牲清晰度的情况下,都可以将视频内容完整的记录下来。那么对于这种情况,目前业界又是怎么做的呢?

主要有以下几个场景:

  1. 明暗/真假水印

明水印指的是打在明处的水印,暗水印相反,真水印指的是直接合成在视频帧内的水印,假水印则是在视频之上,添加一个水印元素。加水印本质上并不能防盗,但是能够给予录屏者一些威慑,并在泄露源追溯的时候起到一定作用。

  1. 弹出式广告或者弹窗

通过在播放过程中弹出广告或者弹窗,增加录制者的操作成本(尽管看起来这做法很low,但是应该是一个还不错的猫)

  1. 检查底层录屏API

这个具体如何实现的就不是很理解了,但是会出现一些误杀的可能,因为不仅仅是录屏的时候才会使用这些API,某些其他软件可能也会在用,所以不能很准确。

  1. 通过数据库???

这个就真的是不懂了,看网上资料有提到,这里也就提一嘴

但是其实无论怎么做,对于录屏这个事情是无法预防的,即使你把播放视频的机子的录屏功能全部干掉了,那还能影响我拿另一台机子录不成?

目前各大视频网站的加密方式是怎样的,以及破解

说了那么多,能看到这里的人估计也是被我的文笔所吸引了(咳~呸!!)。咳咳,不是,应该也是对视频有浓烈的兴趣(毕竟我也是知道我的水平与文笔的)

那么不能光说不练,俗话说得好,读万卷书不如行万里路。无论怎样我们都是要实操一下的,确认一下目前视频加密究竟是不是跟我们讲的一样。

那么说干就干,接下来开始尝试对国内的视频站点进行破解。

首先被选中的是某酷视频,让我们恭喜它。某酷视频也算是国内top5的视频站点了,背靠阿里爸爸,想来不会让我们失望。

某酷

由于我是一个前端开发工程师,所以自然而然的就从web视角尝试破解,而且web破解相对于客户端,肯定是要简单很多,如果把web破解了,那么客户端就没有必要了,因为客户端有的资源,web也有。

在破解之前先简单叙述一下破解思路:

首先要可以自由自在,无拘无束的控制它网站的脚本,所以要使用代理工具将播放器的js脚本代理到本地,从而达到随心所欲调试的效果。这里我用的是charles,当然用fiddler效果也是一样的。

可以自由自在的控制脚本之后,就可以搞清楚某酷的vip视频是怎么搞的了,(这里我就找了几个电影。动漫,综艺,电视剧进行观察,所以可能不是很准确),首先,基本上使用的是hls的视频格式,但是将视频文件直接保存到本地之后无法播放,再看看代码逻辑,可以知道它自己实现了一套加密算法,跑在浏览器进行实时解密与解封装(观察到是混杂在一起,破解起来应该比较困难)。其次对于一些热门影片&好莱坞大片,都用了DRM进行加密,这部分无法破解。

这样我们就基本搞清楚了,某酷的VIP视频主要有两种加密方式组成,1是它自己实现的加解密,2是DRM加密,由于DRM无法破解之外(至少我能力不足),它自己实现的那套加密还是可以破解的。

当然首先需要一个VIP账号(或许你会说,你都有VIP了还破解个毛啊,但是年轻人,我的破解的含义是可以将视频以文件的形式保存下来,并且可以传播给别人播放,而且你没有VIP连视频资源都不可能拿到,还谈什么破解)。

前面也说到了某酷主要是使用hls的视频格式,但是大部分浏览器是不支持这种格式播放的,那么它必然使用了MSE进行进行数据传递,而且解密视频也需要在js层面操纵视频数据,那么这中间就有隙可寻了,既然视频是在js层解密的,那么是不是意味着解密后的视频数据本身在js内就可以拿到,而之前已经将播放器的js代理到本地了,那也就意味着我们可以对可播放的视频解密数据为所欲为了。那么也就意味着,完全不用理会解密算法,解密key,它们全都要为我打工,我只需要解密后的视频数据就够了,这些复杂的逻辑完全不必区管它。

ok,第一步难关已经过了,我们已经可以拿到完整的视频解密后的数据了。那么我们拿到数据之后要做什么呢?当然是想办法再封装成视频啦,video标签本身就没有解密功能,而mse自然更是没有啦,所以这个数据我们只需要封装回视频,那么我们就算是破解成功了,出乎意料的粗暴。

但是怎么封装回视频呢?首先在浏览器环境肯定是不可以的了,我们需要将数据传到后端才行。但是怎么传到后端呢?要知道我们解封装之后的视频数据可是一个大大的二进制buffer,而我们一般也就从服务器端获取二进制内容而已,在前端发送二进制内容给后端,还是比较少见的。

这里我就不卖关子了,查了很久都没有找到fetch或者xhr如何上传二进制数据之后,发现websocket可以,果断使用socket.io实现一个简单的socket连接,果然是可以传递的,但是需要注意的是由于是自己起的后端服务,所以跟视频网站的跨域以及保证连接成功才是难点。(socket.io默认对每个连接的传输字节数做了限制,所以会出现断链再重新连的情况,改一下默认配置就好了)

既然已经拿到了视频数据之后就简单多了,我们只需要在后端将每个buffer拼接成一个,再保存成mp4文件就可以了(如果视频时长有问题就多试几次,可能是传输过程中丢失了信息),为什么这里直接保存成mp4就可以了呢,因为在视频站点解密的时候会将视频再次封装成fragment mp4的格式,以便浏览器可以播放(因为兼容性),所以我们直接保存成mp4就可以了。注意这里的会有音频的buffer数据 与视频的buffer数据,将它们分别保存成文件之后,再通过ffmpeg就可以再次合并成一个音视频齐全的完整视频了。

到这里我们就可以完整的保存某酷的视频了,可以看到很简单粗暴,但是确实是我趟过很多坑才总结出来的,这些坑包括如何将二进制数据传递给后端,本地服务与视频网站http协议不同导致的跨域,某酷脚本使用了AMD与本地soket脚本不兼容等等问题。

其实这里还是有点小缺陷的,因为是在浏览器端获取视频解密信息的,所以要依赖某酷自身的视频解密速度,在且要在保证顺序的情况下获取数据,这就限制了数据的获取速度。但是严格来说我们完全可以将它整个视频解密算法搬到我们的后端,那么我们只需要拿到视频原文件与视频解密的key,就可以在后端很快且完整的解密出来。但是由于目的仅在于学习,所以就不折腾了。

至此我们的视频解密就到这里,简单测试了一下,除了DRM加密的视频之外,其他的视频都是可以用这个方式破解的,而DRM加密的视频也只是占所有视频的一小部分而已。

但是想到这里我突然想到,并不是所有的浏览器都是支持DRM视频加密的,比如很多的手机浏览器就不支持EME模块(一个浏览器与DRM项连接的模块,这里就不展开了),也就不支持DRM的视频播放了,那么在这些浏览器上面,某酷是如何播放这类视频的呢?

想到就去做,直接打开改成手机浏览器调试,然后打开H5版的某酷视频,发现它居然完全没有加密,直接是fmp4格式的视频,但是清晰度比较低。所以应该是为了保证兼容性(主要是MSE本身也有兼容问题)所以直接采用mp4格式的视频以保证占有所有低端浏览器的量。只是让我没想到的是好莱坞大片不是都要求要上DRM的吗?这是怎么谈下来的(我看某艺是不给播放的,会提示需要在app内播放)。

某艺

其实看了某酷,某艺想象也能知道是个什么状况了,因为压根来说所有使用MSE进行视频播放的网站都可以使用截取视频解密流再封装的形式进行破解。所以不出所料的,某艺也是可以这样破解的,过程就不在赘述了,跟某酷是一样的。这里主要提几点与某酷的区别:

  1. 某艺隐藏了视频的资源列表,所以需要拿到完整的视频文件列表还得花一定的功夫(用的hls),而且它对视频资源还做了连接的重定向,所以获取视频资源来说更麻烦一点。
  2. 它对大部分的普通vip视频完全没做加密,只是做了连接的重定向,所以可以直接拿到视频资源列表然后进行数据的合并。(比某酷随便多了)。
  3. 它的DRM视频覆盖率更低,基本只有好莱坞大片以及少部分国外影片使用了。
  4. 它的H5版本官网,对于DRM视频采用的策略是不播放并提示到App观看。

某讯

某讯比某艺还要更随便一点,甚至视频连接重定向都没,只对资源列表做了缓存(第一次好像还是可以从网络那里拿到的)。DRM覆盖率则仅有好莱坞大片,对于其他的vip视频要么是没加密,最多也就可以使用通用的mse的破解方式进行破解。这里打字打累了,就不再赘述了。

这里主要要注意的一点是:某讯会在视频buffer里随机添加噪音buffer(只有几百 byte),然后导致你获取到视频数据合成的时候,出来的视频遇到这类buffer就不能播了,解决方案也很简单,合并的时候简单判断一下,剔除这类小buffer就可以了。

总结

最后做个总结的话就是(大祥哥式结尾),目前视频加密整体来看差强人意,并没有想象的那么安全,之所以市面上没有大规模出现视频泄露,估计还是有能力的人没有这个意愿以及有对于法律风险的顾虑, 否则破解起来还是非常简单的,像我之前没怎么接触过视频这块,大概一个礼拜左右就可以大概破解出绝大部分的视频了(毫不夸张的说,对于某酷,某艺,某讯,超过90%)。尤其是在网页这种极度不安全的场景, 基本相当于裸奔,但是各大视频站很明显不可能放弃这个大平台。

发表于: 2020-12-05