目录
- Android防录屏和截屏
- 关于WindowManager.LayoutParams.FLAG_SECURE
- 关于Display.FLAG_SECURE
- iOS防录屏和截屏
- 监听截屏
- 录屏监听
需求与安全总是对立的,有新的需求,就有新的接口开放,但随之而来的就是利用新接口或者新接口的使用者(app使用者)不按预期出牌。
简单说,我们打出了一把刀,有人用来切菜,有人用来砍柴,有人却用来行凶… 大概是这个意思,互联网软件行业特别多,尤其是破解、攻击。
言归正传,今天来探讨一下android和ios的防录屏。录屏接口的开放,ios和android开放都比较迟,早期系统都是没有的功能,但随着用户的需求,陆续都开放了录屏的接口。随之而来的就是应用安全-防录屏。典型的应用是金融、银行类的APP。
Android防录屏和截屏
Android比较容易,只需要在 Activity 的onCreate() 方法中添加一行代码:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
一般情况下哪些activity不希望被截屏,添加上述代码,当然,多的话肯定是做一个BaseActivity,BaseActivity中加这行代码就可以。当这样的activity在前台时,用户启动截屏或录屏,系统会提示安全而不能截屏或录屏。从源头就断掉了录屏和截屏。
关于WindowManager.LayoutParams.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.
*
*See {@link android.view.Display#FLAG_SECURE} for more details about
* secure surfaces and secure displays.
*/
public static final int FLAG_SECURE = 0x00002000;
关于Display.FLAG_SECURE
**
* Display flag: Indicates that the display has a secure video output and
* supports compositing secure surfaces.
*
* If this flag is set then the display device has a secure video output
* and is capable of showing secure surfaces. It may also be capable of
* showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}.
*
* If this flag is not set then the display device may not have a secure video
* output; the user may see a blank region on the screen instead of
* the contents of secure surfaces or protected buffers.
*
* Secure surfaces are used to prevent content rendered into those surfaces
* by applications from appearing in screenshots or from being viewed
* on non-secure displays. Protected buffers are used by secure video decoders
* for a similar purpose.
*
* An application creates a window with a secure surface by specifying the
* {@link WindowManager.LayoutParams#FLAG_SECURE} window flag.
* Likewise, an application creates a {@link SurfaceView} with a secure surface
* by calling {@link SurfaceView#setSecure} before attaching the secure view to
* its containing window.
*
* An application can use the absence of this flag as a hint that it should not create
* secure surfaces or protected buffers on this display because the content may
* not be visible. For example, if the flag is not set then the application may
* choose not to show content on this display, show an informative error message,
* select an alternate content stream or adopt a different strategy for decoding
* content that does not rely on secure surfaces or protected buffers.
*
*
* @see #getFlags
*/
public static final int FLAG_SECURE = 1 << 1;
iOS防录屏和截屏
ios 主要是以监听状态。
监听截屏
UIApplication中仅有用户截屏后的通知,应用中只会收到已经截屏的通知并没办法干预(iOS8之后失效)。
// 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 NS_AVAILABLE_IOS(7_0);
监听到之后进行处理:
-(void)viewDidAppear:(BOOL)animated{[super viewDidAppear:animated];[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(screenshots) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
}-(void)screenshots
{UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"[安全提醒]内含个人资金账户。不要截图,录制或分享给他人以保障资金账户安全。" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];[alert show];-(void)dealloc
{[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
}
录屏监听
iOS 11 SDK 中新增了UIScreen的API用以告知应用当前屏幕正在录屏。当UIScreen.isCaptured 为true时,表示当前屏幕正在被录制、镜像或被Airplay 发送。
当录屏状态发生变化时,UIKit会发送UIScreenCapturedDidChange的notification。
基于此,我们可以在应用中接收此通知,来对用户的录屏行为做相应的处理
-(void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];//检查当前设备是否处于录屏状态,这里应该是需要定时器来获取,否则只有加载的时候才会判断UIScreen * sc = [UIScreen mainScreen];if (@available(iOS 11.0, *)) {if (sc.isCaptured) {NSLog(@"录屏中");[self screenshots];}} else {}if (@available(iOS 11.0, *)) {
//注册通知,监测当前设备录屏状态发生变化[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(screenshots) name:UIScreenCapturedDidChangeNotification object:nil];} else {}
}-(void) screenshots
{UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"正在录屏,请注意帐号密码安全问题" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定", nil];[alert show];
}-(void)dealloc
{if (@available(iOS 11.0, *)) {[[NSNotificationCenter defaultCenter] removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];} else {}
}
部分引用
https://www.jianshu.com/p/a94969ddd1dc