流媒體加密

浩麟發表於2017-08-02

本文只討論應用於瀏覽器環境的流媒體協議的加密

為什麼要加密視訊

付費觀看視訊的模式是很多平臺的核心業務,如果視訊被錄製並非法傳播,付費業務將受到嚴重威脅。因此對視訊服務進行加密的技術變得尤為重要。

本文所指的視訊加密是為了讓要保護的視訊不能輕易被下載,即使下載到了也是加密後的內容,其它人解開加密後的內容需要付出非常大的代價。

無法做到嚴格的讓要保護的視訊不被錄製,原因在於你需要在客戶端播放出視訊的原內容,解密的流程在客戶端的話不法分子就能模擬整個流程,最保守也能用螢幕錄製軟體錄製到視訊的原內容(可以通過加水印的方法緩解下)。我們的目標是讓他獲取原內容的代價更大。

常見視訊加密技術

視訊加密技術分為兩種:

  1. 防盜鏈:通過驗證的使用者才能訪問到沒有加密的視訊內容,這種方案存在視訊很容易就被下載的風險,嚴格來說這不屬於加密。這種方式其實是資源訪問授權,它實現起來簡單。
  2. 加密視訊本身:通過對稱加密演算法加密視訊內容本身,使用者獲得加密後的視訊內容,通過驗證的使用者可以獲取解密視訊的金鑰,在客戶端解密後播放。這種方式實現起來流程複雜會帶來更多的計算量。

一般結合這兩種技術一起用,第1種技術很成熟也有很多教程就不再複述,本文主要介紹第2種加密技術。

流媒體加密技術原理

看視訊分為兩種,看點播和看錄播。
要看點播可以通過下載完整個視訊後再看,或者通過流媒體邊下邊看。
看直播只能通過流媒體看最新的畫面。

加密整個視訊的技術很簡單,把視訊看成一個檔案採用加密檔案的技術,這種技術太多就不介紹了。
加密流媒體的技術很少,也很難找到學習資料,本文主要介紹流媒體加密技術。

常見的應用與瀏覽器播放的流媒體傳輸協議有:

  • HLS:Apple 推出的基於 HTTP 協議的 MP4 分片傳輸協議,可用於點播和直播場景。每下載一個分片都需要發生一次 HTTP 請求,所以嚴格來說 HLS 不能稱為流媒體傳輸協議。
  • HTTP-FLV:基於 HTTP 長連線的 FLV 分塊 tag 傳輸協議,可用於點播和直播場景。
  • RTMP:基於 TCP 的 FLV 分塊 message 傳輸協議,用於 Flash 客戶端。

流媒體加密原理

可以看出一個規律這些流媒體傳輸協議都必須把視訊流拆分成連續的小塊之後再被傳送,只不過分塊的大小和視訊容器的格式不一樣而已。

流媒體加密技術的核心就在於對這每一小塊視訊分別使用對稱加密演算法,在服務端加密客戶端解密,通過許可權驗證的使用者才能拿到解密一小塊視訊的金鑰。

為什麼不用 HTTPS 加密

可能有人會問為什麼不用 HTTPS 加密?原因是 HTTPS 在網路傳輸層進行非對稱加密,目的是為了防止中間人竊聽劫持,任何人都可以和我們的伺服器建立 HTTPS 連結獲取到原資料。而視訊加密的目的不是為了防止有中間人竊聽我們的視訊資料,而是要讓視訊資料本身被加密。

為什麼選擇對稱加密

現代成熟的加密技術分為對稱加密演算法和公鑰密碼演算法(非對稱加密)。之所以選擇對稱加密是因為流媒體要求很強的實時性,資料量又很大。公鑰密碼演算法的計算都比較複雜,效率較低,適合對少量資料進行加密。對稱加密效率相對較高,所以流媒體加密首選對稱加密。例如在 SSH 登入的時候會先通過公鑰密碼演算法傳輸一個金鑰,再用這個金鑰用作對稱加密演算法的金鑰,在資料傳輸過程中使用對稱加密演算法來提示資料傳輸效率。

HLS 加密

HLS 是目前最成熟的支援流媒體加密的能應用在瀏覽器裡的流媒體傳輸協議,HLS 原生支援加密,下面來詳細介紹它。

在介紹如何加密 HLS 先了解下 HLS 相比於其它流媒體傳輸協議的優缺點。
優點在於:

  • 建立在 HTTP 之上,使用簡單,接入代價小。
  • 分片技術有利於 CDN 加速技術的實施。
  • 部分瀏覽器原生支援,支援點播和錄播。

缺點在於:

  • 用作直播時延遲太大。
  • 移動端支援還好,PC端只有 Safari 原生支援。

HLS 加密原理

HLS 由兩部分構成,一個是 .m3u8 檔案,一個是 .ts 視訊檔案(TS 是視訊檔案格式的一種)。整個過程是,瀏覽器會首先去請求 .m3u8 的索引檔案,然後解析 m3u8,找出對應的 .ts 檔案連結,並開始下載。

hls
hls

m3u8 檔案是一個文字檔案,在開啟 HLS 加密時,內容大致如下:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:26
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.do?k=1"
#EXTINF:9.901,
http://media.example.com/segment26.ts
#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.do?k=2"
#EXTINF:9.501,
http://media.example.com/segment28.ts複製程式碼

這個檔案描述了每個 TS 分片的 URL ,但這些分片都是加密後的內容,要還原出原內容需要從

#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.do?k=1"複製程式碼

中解析出獲取解密金鑰的URL https://priv.example.com/key.do 和對稱加密演算法 AES-128
獲取到金鑰後再在客戶端解密出原內容。
可以看出啟用 HLS 加密後會多出更多的事情:

  • 針對每個 TS 需要去請求獲取金鑰。
  • 需要多提供一個給客戶端獲取金鑰的鑑權服務。
  • 針對每個 TS 需要去執行對稱加密的解密計算。

這會帶來更多的網路請求和計算量,可能會對延遲和效能造成一定的不良影響。

HLS 加密實戰

支援 HLS 的客戶端都原生支援加密,所以要開啟 HLS 加密你只需要修改你的服務端:

  • 修改 HLS 視訊服務,對 TS 加密,往 m3u8 中加入 EXT-X-KEY 欄位。
  • 提供給客戶端獲取金鑰的鑑權服務,即上面的 https://priv.example.com/key.do?k=1 所指向的服務。

目前大多數雲服務都支援 HLS 加密服務,如果你想直接搭建 HLS 加密服務可以使用 nginx-rtmp-module

HLS 相容方案

目前 HLS 存在相容性問題:

  • 針對桌面端低版本瀏覽器例如 IE,可以使用 Flash 技術來播放 HLS ,詳細使用見開源專案 flashls
  • 針對非Safari高版本瀏覽器例如 Chrome ,可以使用 Media Source Extensions API 去實現播放 HLS,詳細使用見開源專案 hls.js
  • 針對即不原生支援 HLS又不支援 Media Source Extensions 也不支援 Flash 的瀏覽器,常見於部分低版本移動端瀏覽器,我也找不到什麼好辦法。

flashls 和 hls.js 都支援 HLS 加密技術。

破解 HLS 加密

有加密就有破解,在明白 HLS 加密原理後,你想過如何去破解它嗎?先定義下破解成功是指:獲取到視訊加密前的完整原檔案。我想到的方法是:

  1. 先付費買一個可正常觀看受保護視訊的賬號。
  2. 用抓包工具抓下所有網路請求(可以篩選下限制到只儲存 HLS 和 獲取key 的請求,防止儲存太多垃圾資料)。
  3. 第2步儲存下來了加密後的 TS 分片和加密分片所需要的金鑰。
  4. 寫一個指令碼以 m3u8 為索引一一解密出加密後的 TS 分片的原檔案,再把 TS 拼接成完整的視訊原檔案。

似乎破解的難度也不會很複雜。

總結

目前流媒體加密技術還不成熟,除了 HLS 協議提供了方便成熟的方案外,其它協議的加密技術還不成熟。

RTMP 協議提供了一個變種版 RTMPE 可以加密流媒體,原理和 HLS 加密類似,但是我還找不到合適的服務端去支援 RTMPE 協議。

閱讀原文

相關文章