iOS防截屏方案(基于DRM)

背景

在iOS開發(fā)的一些業(yè)務(wù)場景中,可能有一些敏感信息(如付款的二維碼等),我們不希望被隨意傳播。應(yīng)用內(nèi)禁止截屏,可以一定程度上,提高敏感信息被傳播的門檻(可能需要另外一臺手機(jī)拍照,并手機(jī)間傳輸)。

然而,由于iOS系統(tǒng)的特殊性,常規(guī)方法無法完全禁止用戶截屏落地成系統(tǒng)圖片。目前,網(wǎng)上的解決方案,主要有兩種:

    1. 監(jiān)聽截屏后通知(UIApplicationUserDidTakeScreenshotNotification),并進(jìn)行提示。
    1. 讓用戶安裝禁用屏幕快照和屏幕錄制的配置文件。

前者無法禁止截屏內(nèi)容落地,后者閹割了手機(jī)功能,導(dǎo)致其他應(yīng)用也無法截屏。二者均不能滿足需求。

其他刪除本地相冊的方案在新系統(tǒng)上不能滿足需求。

本文在研究了參考資料給出的一些建議,使用DRM最終實現(xiàn)了對控件的防止截屏功能。

該方案有以下特點:

  • 可以做到真正意義防止敏感內(nèi)容落地。
  • 沒有用到私有api,是蘋果原生支持的。
  • 支持主流系統(tǒng)版本。

注: 本文方案只能對敏感控件進(jìn)行防截屏處理,無法做到全局任何位置防截屏(全部控件加drm,代價太大)。

使用DRM實現(xiàn)防止截屏

演示demo: https://github.com/ohswift/VTAntiScreenCapture

蘋果系統(tǒng)是支持DRM(Digital Rights Management,數(shù)字版權(quán)管理)的。它表現(xiàn)在,當(dāng)你播放一個加密了的hls流時,你進(jìn)行截屏(用手機(jī)截屏或用Xcode截屏),該視頻控件會顯示空白。

所以,我們的思路就很清晰了。我們可以把一個敏感信息的控件,轉(zhuǎn)化為帶DRM加密的視頻,然后播放。此后,系統(tǒng)進(jìn)行截屏?xí)r,該控件就會消失,達(dá)到防止敏感內(nèi)容落地的目的。

你可以在敏感信息控件后放個背景,用來在截屏?xí)r敏感控件消失后,做更友好的提示。如demo所示。

演示工程的效果如下:

演示使用DRM防止截屏

如demo所示,截屏截不到真實的內(nèi)容,敏感信息會被過濾。

我們的整個流程差不多如下:

1) 根據(jù)控件內(nèi)容生成mp4文件

2) 啟動webserver

3) 本地播放帶DRM加密的hls流

其中1) 不是重點,我們將放后面講。我們先驗證DRM是否真的可以做到防止截屏。假設(shè),我們已經(jīng)把一個文本內(nèi)容轉(zhuǎn)換為mp4了(demo工程中的text.mp4)。那么,我們首先讓這個視頻可以播放起來。

啟動webserver

我們需要把該mp4拷貝到一個目錄后,啟動webServer,如demo中,我們把它拷到tmp目錄下(演示用,實際可以做到mp4數(shù)據(jù)也不落地)。

[_webServer addGETHandlerForBasePath:@"/" directoryPath:dir indexFilename:nil cacheAge:3600 allowRangeRequests:YES];
[_webServer startWithPort:8989 bonjourName:nil];

然后,就可以播放該mp4流了。

[Self.player playURL:@"http://localhost:8989/text.mp4" inView:self.labelContainer];

播放帶hls加密的流

如果你按上面播放,發(fā)現(xiàn)只是單純的展示內(nèi)容,并沒有防截屏的效果。我們需要加密播放流。

你可能需要一些AVPlayer播放視頻的基礎(chǔ),可以參考[iOS]仿微博視頻邊下邊播之封裝播放器Playing Offline HLS with AES-128 encryption iOS。

當(dāng)你理解了AVAssetResourceLoaderDelegate了后,就可以開始了。我們讓播放器去播放一個私有協(xié)議的m3u8文件。

[self.player playURL:@"jedi://text.m3u8" inView:self.labelContainer];

而當(dāng)它無法解析時,就需要走AVAssetResourceLoaderDelegate,我們在其中,返回寫死的text.m3u8數(shù)據(jù)。

#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-VERSION:5
#EXT-X-TARGETDURATION:1
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="jedi://text.key"
#EXTINF:0.067,
http://localhost:8989/text.mp4
#EXT-X-ENDLIST

m3u8中寫入了mp4的url地址,同時,也通過EXT-X-KEY來描述當(dāng)前的加密key,說明當(dāng)前的流是經(jīng)過加密的。

同樣,這里的key的獲取也是用的私有協(xié)議,同樣需要走AVAssetResourceLoaderDelegate。所以,最終AVAssetResourceLoaderDelegate中的方法看起來如下:

-(BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest{
    NSString *url = loadingRequest.request.URL.absoluteString;
    if ([url isEqualToString:@"jedi://text.m3u8"]) {
        NSData *data = [[self gen_m3u8] dataUsingEncoding:NSUTF8StringEncoding];
        [loadingRequest.dataRequest respondWithData:data];
        [loadingRequest finishLoading];
    }
    else if([url isEqualToString:@"jedi://text.key"]) {
        NSMutableData *data = [NSMutableData dataWithLength:16];
        [data resetBytesInRange:NSMakeRange(0, [data length])];
        [loadingRequest.dataRequest respondWithData:[data copy]];
        [loadingRequest finishLoading];
    }
    
    return YES;
}

這里,我們返回的key是16字節(jié)純0的數(shù)據(jù),其實mp4文件并沒有加密,只是讓系統(tǒng)以為加密了,好在截屏?xí)r進(jìn)行保護(hù)。

如果你看到此,應(yīng)該已經(jīng)基本掌握了防止截屏的大致流程了。如果效果無法達(dá)到的話,可以隨時參照demo中的示例。

編碼生成mp4

這里用AVAssetWriterCVPixelBuffer即可生成mp4。這里參考了https://github.com/caferrara/img-to-video.git的代碼。

VTMP4Encoder中包含根據(jù)view生成mp4的邏輯,這里不展開,感興趣的可以查看代碼。

注:要注意,AVAssetWriter要設(shè)置shouldOptimizeForNetworkUse = YES,讓它支持faststart,否則在m3u8中播放不了。

生成的mp4可以在demo中試用,或在mac端啟nginx配置m3u8測試。

封裝成SDK

TODO。 目前只大概封裝了encoder,完整的封裝,敬請期待。

TODO

  • 優(yōu)化生成mp4算法

  • 獲取mp4也用AVAssetResourceLoaderDelegate實現(xiàn)
    目前mp4獲取主要借助GCDWebServer,下個版本考慮去掉對GCDWebServer的依賴。

  • 添加對錄屏、投屏?xí)r的監(jiān)聽和處理
    目前可以做到防止手機(jī)截屏和通過Xcode的截屏,但沒有監(jiān)控錄屏和投屏(這種監(jiān)聽很容易實現(xiàn),待補(bǔ)充)。

參考資料

1. Prevent screen capture in an iOS app

2. Playing Offline HLS with AES-128 encryption iOS

3. [iOS]仿微博視頻邊下邊播之封裝播放器。

4. img-to-video

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2018年4月18日 周三晴 日記五十九篇 2年級12班王鵬志媽媽 今天室外溫度已高達(dá)39度,很多小伙...
    靜夜思5396閱讀 252評論 0 3
  • 本軟鍵盤適用于移動端,基于jQuery庫(操作DOM簡單點);目前該插件只開發(fā)出三種類型 :支付密碼鍵盤,純數(shù)字鍵...
    冰Q閱讀 6,765評論 10 3
  • 月度目標(biāo)關(guān)注的核心問題回答 我的 6月份的核心目標(biāo)是什么? 1.每天注意休息,關(guān)注自己的身體 累了就及時休息。 6...
    青苗媽2016閱讀 294評論 0 2

友情鏈接更多精彩內(nèi)容