作者 | Seven
导读
在移动端使用的开发进程中,维护用户隐私和使用内灵敏信息安满是一个不可忽视的课题。跟着欺诈手段的升级,“共享屏幕”被欺诈分子一再使用,由于暗码被走漏而导致受害者资产受损的事情层出不穷。只要敞开了“共享屏幕”–本质上是一种录屏,暗码、验证码等重要信息就会有被走漏的可能。避免截屏和录屏成为了一个重要的安全措施,特别是关于金融、医疗、企业和高安全要求的使用。本文将介绍一些在iOS和Android渠道上完成防截屏和录屏的常见战略和办法,以及在百度账户体系上的实践。
全文4431字,估计阅读时间12分钟。
01 技能研究
1.1 Android渠道防截屏战略
Android渠道供给了一个更直接的办法来避免使用内容被截屏或录屏。Google 自 Android 4.2(API level 17)引入 FLAG_SECURE,用于将窗口内容标记为安全,制止在屏幕截图中和非安全的显现器被输出。
/** Window flag: treat the content of the window as secure, preventing
* it from appearing in screenshots or from being viewed on non-secure
* displays.
*
* <p>See {@link android.view.Display#FLAG_SECURE} for more details about
* secure surfaces and secure displays.
*/
public static final int FLAG_SECURE = 0x00002000;
能够在 Activity 中,经过getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE) 来设置。当截屏的时分,体系会弹出一个Toast提示“制止屏幕抓取”;当录屏的时分,当时设备显现正常且能正常操作,看似能够正常录制,但是保存后的视频,都是一片黑色,并没有APP的相关界面。
探究:FLAG_SECURE 是怎么产生作用的
在 Android 图形体系上,一个 Activity 对应创立一个 Surface,每个 Surface 对应 SurfaceFlinger 中的一个 Layer。SurfaceFlinger负责办理、合成一切图层,最终显现在屏幕上。
咱们经过 Android 的 源码SurfaceFlinger.cpp 和 Layer.cpp中,能够看到,activity 中设置 FLAG_SECURE 后,显现的 Surface 都是归于SECURE状况,会阻挠屏幕内容被捕获。
// Call this before holding mStateLock to avoid any deadlocking.
bool canCaptureBlackoutContent = hasCaptureBlackoutContentPermission();
{
...
if (!canCaptureBlackoutContent &&
parent->getDrawingState().flags & layer_state_t::eLayerSecure) {
ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
...
}
1.2 iOS渠道的防截屏录屏计划
在iOS渠道,体系并没有直接供给API,去避免被截屏或录屏。在 iOS13之前,主要是经过监听告诉,然后采纳一些措施。
在 iOS7 上,当用户进行截屏时,体系会发送一个UIApplicationUserDidTakeScreenshotNotification告诉。尽管咱们不能阻挠截屏的产生,但能够使用这一告诉来采纳某些措施,如含糊屏幕、显现正告或许销毁显现的灵敏内容。
// This notification is posted after the user takes a screenshot (for example by pressing both the home and lock screen buttons)
UIKIT_EXTERN NSNotificationName const UIApplicationUserDidTakeScreenshotNotification API_AVAILABLE(ios(7.0));
在 iOS11 上,体系新增了UIScreen的API用以奉告使用当时屏幕正在录屏。当UIScreen.isCaptured 为true时,表明当时屏幕正在被录制、镜像或被Airplay 发送。当录屏状况产生变化时,UIKit会发送 UIScreenCapturedDidChangeNotification 的告诉。
// Object is the UIScreen which changed. [object isCaptured] is the new value of captured property.
UIKIT_EXTERN NSNotificationName const UIScreenCapturedDidChangeNotification API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(visionos);
在 iOS13 上,UITextField 在设置 secureTextEntry 为 true 时,体系在截屏和录屏时,UITextField 所在的内容会被体系烘托为空白区域。咱们能够使用这一特性,把需求视图添加到 UITextField 的子视图上(实践是私有类UITextLayoutCanvasView)来达到避免截屏和录屏的作用。
详细操作:
1、初始化一个textField,并获取其子视图 UITextLayoutCanvasView,下面称为textCanvasView
2、将textCanvasView 添加到操控器的 view 上,作为防护的底层视图
3、将所需防护的 view 添加textCanvasView 上
4、经过事情触发,敞开或封闭textField的secureTextEntry特点; 相当于敞开或封闭防截屏录屏
其中将防护的 view添加到 textCanvasView上,而非添加到 textField 上。由于在暗码模式时,这个view会在截屏或许录屏时躲藏,一起也能够有用避免接触事情的抵触。别的,textFiled 的secureTextEntry特点没有iOS 体系版别限制,在低版别体系上也能够设置,只是在 iOS13及后续版别上,才具有避免截屏和录屏的特性。
另一台手机录制
当时设备录制
在上面视频中红色背景为 textCanvasView,上面添加了需求防护的视图,输入暗码后面的 textfield已敞开 secureTextEntry。
能够看到,未敞开防护时,截屏和录屏的时分,输入暗码的 textfield 内容为空白;敞开防护后,textCanvasView及需求防护的视图均已变为空白。
02 百度账户体系使用实践
在账号登录页,账密登录输入暗码时,以及修正暗码时需求设置避免截屏或录屏。
由于前端本身无法感知到体系的截屏或录屏事情,且不同的前端页面关于防护的需求也有不同,所以规划由前端来操控防护的开关,在 Android 和 iOS 上分端完成详细的防护功用。
2.1 前端使用实践
当进入到账密登录页面或修正页面时,FE 经过端办法操控打开防护,退出页面时,再由端办法来封闭防护。
双端SDK界说的一个端办法名称为 xxx_forbid_record,其中能够经过参数操控是敞开或许封闭。
FE在使用时,能够直接经过 window.location.href来调用起拼接的端办法字符串 xxx://xxx_forbid_record/{“status”:”1″},表明要敞开防护要制止截屏和录屏。双端 SDK分别在体系的回调中进行阻拦,解析端办法,转化为调用对应原生办法。
2.2 Android完成
在基类Activity中初始化 webview时,去设置防截屏回调,能够经过参数操控 敞开或封闭”制止截屏录屏”功用。
在FE调用时,经过阻拦端办法,触发“防截屏回调”,进行实践操控。
如果是敞开,则给 window 添加 FLAG_SCCURE 标志;如果是封闭,则经过 clearFlags 办法清除 FLAG_SCCURE标志。
调用端办法敞开防护的时分,当时设备实践会提示“该使用不允许屏幕截图”,且不会产生屏幕的实践截图。
录屏时,当时屏幕仍然正常显现和操作,但在录屏生成的视频中,敞开防截屏的进程整个屏幕会变成黑色,封闭后防截屏后能够正常显现。
△截屏作用
2.3 iOS完成
在 百度账号 SDK 中,由于经过textfield特性来完成放截屏录屏并不是苹果体系揭露的正式 API,从稳定性视点考虑,当时仅是监听了截屏和录屏的告诉,经过添加弹窗,提示录屏或截屏风险。
详细完成为:
1、在webivewController中,监听体系截屏告诉 UIApplicationUserDidTakeScreenshotNotification,如果是 iOS 11 及以上体系,则一起监听录屏告诉 UIScreenCapturedDidChangeNotification。
2、区分录屏 或 截屏场景,进行提示。
3、FE 敞开或封闭,SDK中阻拦的端办法完成中,设置本地的标识为敞开或封闭。
当 FE敞开防截屏录屏后,SDK阻拦端办法后会首要经过 [UIScreen mainScreen].isCaptured 办法,判别当时是否现已录屏。如果是,则直接弹窗提示。
当收到体系截屏或录屏的告诉时,sdk 会判别满意以下两个条件都满意才会进行提示:
1)本地的标识为敞开
2)当时页面正在展现
当时页面正在展现上经过 view.window 对象存在,以及 操控器的 isViewLoaded 来判别;添加此条件的判别原因是,从登录页能够打开别的一个其他的页面,在该新页面敞开截屏或录屏时,登录页虽然没有显现出来,但仍会接收告诉。如果新页面是不需求敞开防截屏录屏,那么登录页在收到相关告诉后,仅经过本地标识来判别,就出弹出不符合预期的弹窗。
在 百度账号SDK中,当进入暗码登录页时,进行截屏和录屏作用如下。
截屏提示
录屏提示
03 总结
防截屏录屏功用是移动使用安全的一个要害组成部分,特别是关于处理灵敏数据的使用而言。iOS 虽然未和 Android 一样有体系供给直接的 API,但上述战略和技能能够明显降低信息走漏的风险。开发者在规划使用时,需求权衡用户体验和安全需求,实施适合自己使用场景的防截屏录屏计划。
——END——
推荐阅读
百度查找内容HTAP表格存储体系 本文将介绍一些在iOS和Android渠道上完成防截屏和录屏的常见战略和办法,以及在百度账户体系上的实践。