(西安理工大學 自動化與信息工程學院,西安 710048)
如今視頻監控技術取得了很大的進步,用戶無論身在何處,只要能夠連接網絡就能夠隨時訪問監控攝像頭。由于網絡的開放性,視頻監控在給人們提供信息的同時,視頻監控的安全問題也逐漸顯現,日益威脅公眾隱私和治安管理[1]。顯然監控視頻信息在傳輸過程中,存在外泄的可能,同時信息也可能被篡改而導致不完整[2]。因此,加強對監控視頻信息安全的研究,擁有一個既能保證用戶使用便利又能保障信息安全的視頻監控加密系統,對公眾而言具有重要的意義。
傳統的視頻監控系統普遍使用實時傳輸協議(real-time transport protocol,RTP)傳輸監控視頻,并配合使用實時流傳輸協議(real-time streaming protocol,RTSP)對視頻進行控制。使用這些協議的流媒體系統,服務端需要專門的流媒體服務器支持,實現起來較為復雜[3]。另外支持RTP/RTSP協議的客戶端所需要的軟硬件資源較多,加密的視頻在瀏覽器端播放需要額外安裝Flash插件,并且Flash這種第三方插件安全性得不到保障[4]。隨著HTML5標準的興起,Web瀏覽器在各方面都有了很大的提升,其原生具有跨平臺的特性[5]。使用現代Web瀏覽器,借助在移動端有良好支持的HTTP Live Streaming(HLS)流媒體傳輸協議[6],可以同時在移動端及個人計算機(personal computer,PC)端在不使用第三方插件的情況下直接播放加密監控視頻。但是這些現有的系統在監控視頻的安全防護方面還存在不足,這些系統要么僅僅采用權限控制的方式保護視頻,并沒有對視頻本身加密;要么使用HLS協議中AES-128加密方法對監控視頻中所有數據都進行了加密。然而這些視頻數據中有一些非必要的內容是不需要加密的,只要將關鍵數據保護好就能保障視頻的安全。更多的加密量需要更多的加密周期,過多的加密周期進而會產生不必要的資源消耗,特別是對資源有限的客戶端來說,在解密視頻過程中不可避免地占用過多的CPU及內存資源,影響用戶體驗。
針對以上問題的不足,本文對現有的視頻監控加密系統進行優化設計,將HLS協議中的SAMPLE-AES加密方法應用到系統中,對視頻中少量的關鍵數據進行加密,對大量的非關鍵數據不加密。在保證安全性的同時,客戶端播放視頻時能夠有效減少CPU及內存資源的占用,降低客戶端資源的消耗。并借助HTML5及媒體源擴展(media source extensions,MSE)技術,實現加密監控視頻在PC端、iOS移動端、Android移動端的瀏覽器中無插件地播放的目的。
本視頻監控加密系統基于HLS協議,能夠將網絡監控攝像頭中的視頻流實時編碼為HLS流媒體,同時對視頻中的關鍵數據進行選擇性加密保護,經過身份驗證后客戶端能夠在全平臺瀏覽器無插件地播放監控視頻。該系統分為監控視頻源、服務端和客戶端,其中服務端包括編碼加密模塊、內容分發模塊、身份認證模塊。視頻監控加密系統整體架構如圖1所示。

圖1 視頻監控加密系統整體架構
如圖1可知,監控視頻源為網絡監控攝像頭,采集視頻數據并向服務端提供視頻流。服務端通過攝像頭提供的視頻地址獲得視頻流,編碼器將視頻流進行指定格式的編碼,同時調用加密器對視頻流進行SAMPLE-AES加密,加密后封裝為MPEG-2傳輸流(transport stream,TS)。然后分割器將TS流切分為TS切片文件并產生索引列表文件,并提供給內容分發模塊。客戶端想要播放視頻,首先通過統一資源定位符(uniform resource locator,URL)地址向內容分發模塊發送請求,并經過身份認證模塊的驗證。認證通過后獲得所需文件,進一步解密視頻,并轉換為瀏覽器指定的格式進行播放。
監控視頻源由RTSP網絡監控攝像頭提供,網絡監控攝像頭由模擬攝像模塊和網絡編碼模塊組成。在網絡監控攝像頭內部,模擬攝像模塊采集模擬媒體信號,經過編碼模塊變換成數字媒體流信號,然后將其編碼后封裝到RTP包中,并通過有線或無線以RTSP視頻流的形式輸出。
編碼加密模塊包括編碼器、加密器和分割器。
2.2.1 編碼器
編碼器負責將從監控視頻源接入的RTSP視頻流實時編碼并重新封裝。首先讀取來自網絡攝像頭的RTSP視頻流,解析視頻流中RTP數據包并得到原始基本流(elementary stream,ES),將視頻ES基本流進行H.264編碼,音頻ES基本流進行AAC編碼。在編碼后的ES基本流的包頭中分別添加顯示時間標記(presentation time stamp,PTS)、解碼時間標記(decoding time stamp,DTS)并打包成分組基本流(packetized elementary streams,PES)。最后將節目專用信息(program specific information,PSI)加在PES流上并經過復用器將視頻數據封裝到MPEG-2 TS傳輸流中。具體封裝過程如圖2所示。

圖2 封裝成TS流具體過程
如圖2所示,在將進行了H.264編碼、AAC編碼之后的音視頻ES流打包之前要做一個判斷,如果監控視頻不需要加密,則進行下一步的打包封裝操作;如果需要加密,則調用加密器,對音視頻進行加密后再進行打包封裝操作。
2.2.2 加密器
加密器使用SAMPLE-AES樣本加密方法,先對音視頻ES基本流進行加密再對其打包封裝。首先生成128位的密鑰文件用于加密并將URL地址發送給分割器,同時選擇需要加密的數據塊為下一步加密做準備。H.264視頻加密塊是指定類型的網絡提取層(network abstraction layer,NAL)單元,音頻加密塊是音頻幀。每個需要加密的NAL單元或音頻幀都包含整數個16字節塊。然后使用128位密鑰文件采用AES加密算法[7]的密碼塊鏈接(cipher block chaining,CBC)模式對16字節數據塊進行加密,無需填充,在每個NAL單元或音頻幀的開始處初始化向量(initialization vector,IV)被重置為其原始值。下一步的封裝及分割不會對加密的音視頻產生影響。
對H.264視頻具體加密過程如圖3所示,只加密類型為1和5的NAL單元,其他類型NAL單元不加密。
以下是加密的NAL單元的代碼格式:
Encrypted_nal_unit(){
nal_unit_type_byte // 1個字節
unencrypted_leader // 31個字節
while(bytes_remaining()> 0){
if(bytes_remaining()> 16){
encrypted_block // 16個字節
}
unencrypted_block //1-144字節
}
}
每個加密的NAL單元都包含防止二義性的前綴,即包含nal_unit_type值的字節和后面的31個字節,前綴不加密。未加密字節后面是需要加密的數據塊。任何長度不超過16個字節的數據塊都不需要加密,因此長度為48字節或更少的NAL單元是完全未加密的。
如圖3,使用10%跳過的加密方式對NAL單元數據塊加密。即先加密16個字節的數據塊,然后跳過剩下的90%,后面最多有9個16字節即144字節的數據塊不加密,第10個16字節數據塊繼續進行加密,接下來加密形式以此類推。其他類型為1和5的NAL單元只要長度大于48字節,在被加密時,要在整個NAL單元上再次加上前綴。

圖3 H.264樣本加密流程圖
客戶端在解密H.264視頻時,首先需要識別類型為1和5同時長度大于48字節的NAL單元,然后除去防止二義性的前綴。最后定位到NAL單元的加密部分,并解密該部分的數據。
AAC音頻流的加密數據塊是包含音頻數據傳輸流(audio data transport,ADTS)頭的音頻幀,加密格式如下所示:
Encrypted_AAC_Frame(){
ADTS_Header // 7或9個字節
通過地面直達波或者反射波模型獲取土壤介質的平均介電常數ε,即可以利用CRIM模型可以計算表層土壤的平均體積含水量:
unencrypted_leader // 16個字節
while(bytes_remaining()> = 16){
encrypted_block // 16個字節
}
unencrypted_trailer // 0-15個字節
}
ADTS頭可以是7或9個字節長,加上后面音頻幀的前16個字節,這些數據不加密,隨后的連續數據部分被加密。加密部分的大小必須是16字節的整數倍,并且可能為零。
2.2.3 分割器
分割器負責將編碼后的MPEG-2 TS流切分成一系列連續且播放時間相等的很小的TS切片文件,然后將其發送到內容分發模塊進行存儲。這些切片文件的大小由用戶提前設定。如圖4中所示,切分過程中要將DTS差值與用戶設定的時間長度進行比較,只有達到用戶設定的長度時才生成當前切片文件。在對TS傳輸流進行具體分割時要注意每個切片文件中都必須含有一個節目關聯表(program association table,PAT)和一個節目映射表(program map table,PMT),同時還要保證必須含有至少一個關鍵幀和序列頭等信息,從而完成解碼器的初始化。

圖4 TS切片文件生成流程圖
切分過程中要根據媒體流中每幀圖像的DTS值來計算DTS差值。DTS差值算法流程如圖5所示。每生成一個新的TS切片文件,都要記錄第一幀圖像的時間戳并記作LastTimestampInStream,將該時間戳作為該切片文件的起始時間。后續的圖像都要根據其當前時間戳CurrentTimestampIntream減去起始時間LastTimestampInStream,從而計算出當前TS切片文件的時長。當DTS差值達到用戶提前設定的TS切片文件時長時,便關閉當前TS切片文件,準備進行下一個TS切片文件的寫入。

圖5 DTS差值算法流程圖
在對TS傳輸流進行分割的同時,分割器還要創建一個含有這些TS切片文件URL地址的M3U8索引列表文件,同樣發送到內容分發模塊存儲。每當分割器生成一個新的TS切片文件時,這個M3U8索引列表文件將會更新,新生成的TS切片的URL地址加入到索引列表文件末尾,同時時間最久的處于索引列表開頭部分的切片文件URL地址被移除。如果視頻數據被加密,還需要添加#EXT-X-KEY:METHOD=SAMPLE-AES,URI=”KEY文件的地址”標簽,表示視頻已經使用SAMPLE-AES加密方法加密,并指出相應的加密密鑰文件的URL地址。
內容分發模塊是一個標準的Web服務器,負責將加密并分割后的TS切片文件、密鑰文件及M3U8索引列表文件通過HTTP傳輸協議發送到請求的客戶端。為了進一步增加傳輸過程中的安全性,本系統中索引列表文件及密鑰文件采用HTTPS協議進行傳輸層安全性協議(transport layer security,SSL)加密后發送給客戶端。要支持HLS協議規定的媒體類型文件的GET請求,只需要在Web服務器的媒體多用途互聯網郵件擴展(multipurpose internet mail extensions,MIME)類型中添加如表1所示配置[8]。

表1 媒體MIME類型配置
對于被加密的監控視頻,由于其M3U8索引列表文件中直接列出了TS切片及密鑰文件的URL地址,只要獲得了索引列表文件,直接就能獲得密鑰文件并解密視頻。因此本系統對索引列表文件及加密密鑰文件同時設置了訪問權限驗證,確保了由加密、傳輸以及訪問權限控制的整個過程的安全。
本模塊采用的是基于Token的身份認證機制[9],相對于傳統的Cookie/Session機制,Token認證擴展性更強、更安全,有支持跨域訪問、無連接狀態、去耦合化和更好的性能體驗等優勢。Token在服務端產生,客戶端使用用戶名和密碼向身份認證模塊請求認證,認證成功后服務端為其頒發一個獨有的Token 憑證。客戶端可以在每次請求密鑰文件的時候在 HTTP 請求的頭部分附加Token證明自己的合法身份,Token認證過程如圖6所示。為了保證用戶名、密碼在驗證過程以及Token信息在傳輸過程的安全,采用HTTPS協議對其進行SSL加密后傳輸。

圖6 Token認證過程圖
客戶端包括PC端、iOS移動端、Android移動端的Web瀏覽器,用戶在瀏覽器上首先經過身份驗證,認證通過后通過指定的URL地址,基于HTTP請求來獲取和下載索引列表文件,并通過索引列表進一步獲得TS切片文件和密鑰文件。接下來瀏覽器用密鑰文件解密TS切片并將解密后的TS切片直接便捷地使用HTML5中新增的
目前現代瀏覽器都支持MTHL5技術和MSE技術,但是PC端一些主流瀏覽器(如谷歌瀏覽器、火狐瀏覽器)還不支持HLS協議中的TS傳輸流。為了使這些主流瀏覽器也能夠無插件播放視頻,本系統在客戶端請求的網頁中嵌入了hls.js開源庫[10]。
開源庫hls.js基于HTML5和MSE技術,原理是通過調用MSE API來使用JavaScript不使用任何插件動態地將MPEG-2 TS傳輸流轉換為MP4片段并提供給
本系統的開發環境為CentOS Linux 7操作系統,網絡攝像頭型號為海康威視DS-2CD1221D-I3,根據攝像頭的型號得到監控視頻取流的RTSP地址,本系統采用默認的用戶名密碼,地址為:rtsp://admin:12345@172.6.22.234:554/ Streaming/Channels/101?transportmode=unicast。然后將這個RTSP視頻流地址提供給服務端編碼加密模塊中的編碼器。
編碼加密模塊基于FFmpeg開源編解碼框架,首先通過調用AVInputFormat結構體中的ff_rtsp_demuxer函數解析RTSP視頻流;然后調用AVCodec結構體中的ff_libx264_encoder函數對視頻進行編碼;最后調用AVOutputFormat結構體中的ff_mpegts_muxer函數和ff_stream_segment_muxer函數將依次對視頻進行封裝和切分。需要對其中ff_libx264_encoder函數中的X264_frame()函數進行修改,在encode_nals()函數后添加擁有SAMPLE-AES加密功能的nal_sample_encrypt()函數,用于對編碼后NAL單元進行加密。
內容分發模塊采用內存占用小、性能穩定的Nginx作為Web服務器。身份認證模塊沒有單獨另外搭建一個認證服務器,而是通過將lua語言嵌入到高性能的Nginx服務器中,使Nginx可以高并發、非堵塞地處理Token認證請求,并利用redis鍵值數據庫的超時機制設置Token時效性來控制Token的有效性。由于OpenResty是一個集成了Nginx與lua的高性能Web平臺[11],因此本系統直接安裝OpenResty與redis,共同實現內容分發及Token認證的功能。安裝后需要編寫lua腳本實現Token驗證,包含的主要腳本有:auth_req_headers.lua,請求頭校驗腳本,失敗直接中斷請求;auth_token.lua,Token處理腳本;handle_cors.lua,請求跨域腳本;handle_request_provision.lua,請求handle入口腳本;redis_mcredis.lua,redis操作工具的封裝腳本;tool_dns_server.lua,域名解析,獲取域名對應IP,并設置緩存的腳本。
系統搭建好之后,觀察播放效果,如圖7所示,PC端的谷歌瀏覽器,iPad端的Safari瀏覽器、Android端谷歌瀏覽器及微信端網頁各個平臺都能滿足使用HTML5技術直接無插件地播放加密監控視頻。

圖7 各個平臺播放效果圖
NAL單元中最重要的單元類型是1和5,包含了所有的視頻數據。類型為5的NAL單元負載中包含的是立即刷新圖像(instantaneous decoding refresh,IDR)的圖像片段,類型為1的NAL單元負載包含的是非IDR幀的圖像片段,解碼器在收到IDR數據單元后會立即刷新所有圖像,并作為之后的所有數據的解碼參照。因此對這些最重要的包含了圖像片段的NAL單元類型進行選擇性加密,即使其他類型不加密,非授權用戶也無法正確解碼視頻。并且加密過程采用的是AES加密算法,AES加密算法為新一代數據加密標準,能夠同時滿足強安全性、高效率、高性能、易用和靈活的特點[7]。AES加密算法是目前可獲得的最安全的對稱加密算法,密鑰長度達到128位就能達到保護機密信息的標準。另外NAL單元中相對固定的頭部信息沒有加密,可以有效防止明文攻擊。在沒有密鑰的情況下播放加密的監控視頻效果如圖8所示。

圖8 加密后播放效果圖
同時,本系統采用高度安全的HTTPS協議對索引列表文件及密鑰文件進行傳輸,給攻擊者增加了巨大的難度,根本無法獲得密鑰信息。客戶端采用了安全性更高的基于Token的身份認證機制有效攔截了非授權用戶的播放。
將本系統與現有使用AES-128加密方法的其他監控加密系統進行對比,檢測客戶端播放加密視頻過程中的CPU占用率及內存使用率。采用同一個監控視頻源,相同播放平臺,都是借助HTML5進行播放,不同的是監控視頻在不同加密系統中使用不同加密方法加密。
本次實驗的播放平臺選用內存為16 GB,處理器為Inter i5-4590 CPU@3.30 GHz x 4的 PC端的谷歌瀏覽器。客戶端在播放視頻過程中CPU使用率對比結果如圖9所示,客戶端內存占用率對比結果如圖10所示。

圖9 客戶端CPU消耗對比

圖10 客戶端內存占用率對比
由圖10及圖11實驗結果可知,本系統由于采用SAMPLE-AES加密方法,沒有對所有視頻數據都進行加密,而是對監控視頻中包含視頻片段的NAL單元進行選擇性加密,從而有效減少加密周期,進一步降低了客戶端解密過程的復雜度,減少了在CPU占用及內存使用中而產生的不必要的消耗,用戶體驗得到有效提升。
本文對現有的視頻監控加密系統進行了優化設計,將HLS協議中的SAMPLE-AES加密方法應用在系統中,選擇性地加密視頻中的關鍵數據。與現有系統相比,在保證安全性的同時播放加密視頻的客戶端CPU及內存消耗明顯
減少。并借助HTML5及MSE技術,實現了全平臺瀏覽器無插件地播放加密監控視頻。這種視頻監控加密系統在安防領域有廣泛的應用前景。