白盒加密解决什么问题
普通 AES 的致命弱点:密钥必须以明文形式出现在内存里(哪怕一瞬间),hook 就能拿走。白盒 AES(White-Box AES)的设计目标是"密钥永不出现"——把密钥和 AES 算法预计算融合成一堆查找表,加密过程就是查表,密钥本身从数学上"溶"进了表里。
金融 App、支付 SDK、DRM 系统(如 Widevine)是白盒的主要用户。
识别:白盒 AES 长什么样
SO 里识别白盒 AES 的特征:
- 没有 AES 特征常量(S 盒搜不到——它被融进自定义表了)
- 大量自定义查找表:数据段里有几 KB 到几百 KB 的神秘表数据
- 加密函数全是查表+异或:没有明显的轮函数结构,就是循环地"取字节 → 查表 → 异或"
- 性能异常:比标准 AES 慢 10-50 倍(查表开销)
Java 层线索:WhiteboxCrypto、WBAES 类名,或加密库加载了异常大的 SO。
攻击面一:别硬刚,先换路
面对白盒 AES,第一原则是绕开而不是攻破:
- Frida 直调:白盒防的是"提取密钥",不防"调用加密功能"。hook 加密函数直接调,密钥提不提取无所谓——我要的是加密能力,不是密钥本身
- hook 输入输出:加密前后的数据在函数边界是明文,hook 拿到就行
90% 的业务需求(协议模拟)到这里就解决了。只有需要"离线独立加密"(脱离 App 环境)时,才需要真正攻击白盒。
攻击面二:故障注入分析(DFA)
学术界对白盒 AES 的标准攻击是差分故障分析:在加密过程特定轮次注入故障(改一个字节),对比正常密文和故障密文,反推轮密钥。
工程实现:Frida hook 加密过程,在倒数第 3-4 轮的查表结果上随机改字节,收集几百组"正常密文 + 故障密文"对,用开源 DFA 工具(如 phoenixAES)求解密钥。
// 思路示意:hook 白盒查表的中间点,随机翻转一字节
Interceptor.attach(tableLookupAddr, {
onLeave: function(retval) {
if (Math.random() < 0.5) {
// 注入故障
this.context.x0 = this.context.x0 ^ 0x01;
}
}
});DFA 的前提是能找到"倒数第几轮"的注入点——需要先静态分析白盒的查表结构,定位轮边界。
攻击面三:直接抠表复刻
白盒的表就是"密钥的化身"——把表整个抠出来,自己实现查表引擎,等于完整复制了加密能力:
- IDA 里定位所有表数据(数据段的连续大数组)
- dump 表到文件
- 按白盒的查表逻辑(静态分析得到)写自己的查表加密器
工作量比 DFA 大,但产物是"可离线运行的完整加密器",不依赖 App 环境。
精髓:白盒的真实强度
- 白盒提高的是"密钥提取"的成本,不是"能力盗用"的成本。Frida 直调完全不受白盒影响——这决定了白盒在实战中的尴尬地位:防得住密钥泄露,防不住功能借用
- 白盒实现质量参差。自研白盒(非成熟方案如 wbaes 库)常有结构缺陷:表没做外部编码(external encoding),输入输出直接是 AES 明文密文——这种直接抠表就等于拿到了 AES 密钥等价物
- 配套防护才是完整体。成熟方案会把白盒和反调试、完整性校验、代码混淆打包——攻击白盒前要先过这些外围,工程规划时把外围成本算进去
总结
- 白盒 AES = 密钥溶进查找表,识别特征是无 S 盒 + 大量自定义表
- 90% 场景 Frida 直调解决,不碰密钥提取
- 真要攻:DFA 故障注入或抠表复刻
- 白盒防密钥提取不防功能借用,实战地位尴尬
交流微信:run1255