第1章 项目概述与防录屏需求分析

支付键盘是移动支付安全链条中最薄弱也最关键的环节——用户输入的每一位密码、每一个卡号,都暴露在系统录屏 API 的可视范围之内。本章从真实攻击场景出发,分析防录屏的必要性,讲解 FLAG_SECURE 的核心原理,厘清防录屏与防截屏的技术差异,并明确本课程的最终交付物和学习目标。

1.1 支付键盘安全场景

当用户在支付键盘上输入敏感信息时,以下三类攻击场景构成直接威胁:

  • 恶意录屏攻击——后台应用通过 MediaProjection 或 AccessibilityService 录制屏幕,直接捕获键盘按键图像;
  • 截屏信息窃取——攻击者利用系统截屏快捷键(如电源键+音量键)在支付页面按下瞬间保存键盘布局与输入内容;
  • 屏幕共享泄露——视频会议、远程协助或直播过程中,支付键盘无意间被第三方观众完整观看。
安全风险提示:支付键盘如果不做防录屏处理,所有输入内容(密码、CVV、身份证号)在录屏文件中以明文图像形式存在,一次录屏即可批量窃取多位用户的敏感信息。

1.2 FLAG_SECURE 原理

FLAG_SECURE 是 Android WindowManager 提供的一个窗口标记位。当一个窗口设置了该标记,系统会在所有屏幕采集流程中对该窗口的内容做黑化/空白化处理:

  • 系统截屏(硬件按键)→ 标记窗口显示为黑色或空白;
  • MediaProjection 录屏 → 标记窗口在帧缓冲区中被填充为纯色;
  • 显示投射 / 无线投屏 → 标记窗口内容被屏蔽。

在 Activity 或 Compose 中设置 FLAG_SECURE 的方式如下:

// 方式一:在 Activity.onCreate() 中设置
class PaymentActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setFlags(
            WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE
        )
        setContent {
            PaymentKeyboardScreen()
        }
    }
}
// 方式二:通过 Compose 的 LocalView 访问 Window
@Composable
fun SecurePaymentKeyboard() {
    val view = LocalView.current
    DisposableEffect(view) {
        val window = (view.context as? Activity)?.window
        window?.setFlags(
            WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE
        )
        onDispose {
            window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
        }
    }
    // 键盘 UI 绘制
}
原理透视:FLAG_SECURE 并非加密或混淆,而是直接在 SurfaceFlinger 合成层屏蔽窗口内容。任何屏幕采集源(包括 adb screencap、第三方录屏应用)都无法绕过这一层屏蔽,除非拥有系统权限(root)。

1.3 防录屏与防截屏区别

两者在攻击面、实现层次和防护效果上存在本质差异,不可混用:

对比维度 防录屏 (FLAG_SECURE) 防截屏 (系统层拦截)
攻击方式 屏幕录制、直播共享、投屏采集 物理按键截屏、辅助功能截屏
防护原理 窗口标记→SurfaceFlinger 屏蔽 截屏广播拦截 / KeyEvent 消费
实现层次 应用层 Window 标记 系统层 Input 事件 + 广播接收
覆盖范围 仅标记窗口内的所有视图 可拦截全局截屏快捷组合键
绕过难度 需 root 或 Xposed 框架注入 需修改系统事件分发流程
对用户影响 正常使用无感知 可能影响用户截屏习惯
关键结论:FLAG_SECURE 能有效防御录屏但无法阻止物理截屏按键;系统截屏拦截能防截屏却对 MediaProjection 录屏无效。支付键盘必须同时部署两种防护策略,形成纵深防御。
支付键盘防录屏安全需求总览 支付键盘防录屏安全需求总览 恶意录屏窃取 截屏信息收集 屏幕共享泄露 ▼ 威胁层 FLAG_SECURE 标记 Compose 自定义绘制 安全区域检测 ▼ 防护层 防录屏支付键盘组件 ▼ 交付层 安全目标:所有支付敏感输入场景必须同时防御录屏与截屏攻击

1.4 课程目标与交付物

本课程以 工程化交付 为导向,你将掌握以下核心能力:

  • 理解 Android 窗口安全体系与 FLAG_SECURE 底层机制;
  • 在 Jetpack Compose 中实现不可录屏的自定义支付键盘;
  • 掌握安全键盘的输入事件分发、按键防泄露与焦点管理;
  • 构建一套可集成到真实支付场景的防录屏键盘组件库。

课程最终交付物清单:

交付物 说明 技术要点
SecureKeyboard 组件 防录屏支付键盘 Compose 组件 FLAG_SECURE + Canvas 自定义绘制
SecureTextField 输入框 支持密码/卡号的安全输入控件 输入事件安全分发 + 防嗅探
SecurityPolicy 策略模块 窗口标记动态管理与策略配置 FLAG_SECURE 生命周期绑定
Demo 示例工程 完整可运行的支付键盘演示应用 组件集成、调试与验证
学习建议:本章是后续所有技术实现的基础。建议在真机上测试 FLAG_SECURE 的实际效果——使用任意录屏应用录制本节的 Demo Activity,观察标记窗口在录屏文件中的呈现方式,建立直观的“安全边界”认知。