百趣云 百趣云的博客

白盒 AES:把密钥藏进查表里的防护与攻击面

白盒加密解决什么问题

普通 AES 的致命弱点:密钥必须以明文形式出现在内存里(哪怕一瞬间),hook 就能拿走。白盒 AES(White-Box AES)的设计目标是"密钥永不出现"——把密钥和 AES 算法预计算融合成一堆查找表,加密过程就是查表,密钥本身从数学上"溶"进了表里。

金融 App、支付 SDK、DRM 系统(如 Widevine)是白盒的主要用户。

识别:白盒 AES 长什么样

SO 里识别白盒 AES 的特征:

  1. 没有 AES 特征常量(S 盒搜不到——它被融进自定义表了)
  2. 大量自定义查找表:数据段里有几 KB 到几百 KB 的神秘表数据
  3. 加密函数全是查表+异或:没有明显的轮函数结构,就是循环地"取字节 → 查表 → 异或"
  4. 性能异常:比标准 AES 慢 10-50 倍(查表开销)

Java 层线索:WhiteboxCryptoWBAES 类名,或加密库加载了异常大的 SO。

攻击面一:别硬刚,先换路

面对白盒 AES,第一原则是绕开而不是攻破

  1. Frida 直调:白盒防的是"提取密钥",不防"调用加密功能"。hook 加密函数直接调,密钥提不提取无所谓——我要的是加密能力,不是密钥本身
  2. 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 的前提是能找到"倒数第几轮"的注入点——需要先静态分析白盒的查表结构,定位轮边界。

攻击面三:直接抠表复刻

白盒的表就是"密钥的化身"——把表整个抠出来,自己实现查表引擎,等于完整复制了加密能力:

  1. IDA 里定位所有表数据(数据段的连续大数组)
  2. dump 表到文件
  3. 按白盒的查表逻辑(静态分析得到)写自己的查表加密器

工作量比 DFA 大,但产物是"可离线运行的完整加密器",不依赖 App 环境。

精髓:白盒的真实强度

  1. 白盒提高的是"密钥提取"的成本,不是"能力盗用"的成本。Frida 直调完全不受白盒影响——这决定了白盒在实战中的尴尬地位:防得住密钥泄露,防不住功能借用
  2. 白盒实现质量参差。自研白盒(非成熟方案如 wbaes 库)常有结构缺陷:表没做外部编码(external encoding),输入输出直接是 AES 明文密文——这种直接抠表就等于拿到了 AES 密钥等价物
  3. 配套防护才是完整体。成熟方案会把白盒和反调试、完整性校验、代码混淆打包——攻击白盒前要先过这些外围,工程规划时把外围成本算进去

总结

  1. 白盒 AES = 密钥溶进查找表,识别特征是无 S 盒 + 大量自定义表
  2. 90% 场景 Frida 直调解决,不碰密钥提取
  3. 真要攻:DFA 故障注入或抠表复刻
  4. 白盒防密钥提取不防功能借用,实战地位尴尬

交流微信:run1255

By 百趣云 阅读量:53 On