如何安全地归零和释放 Android 应用程序使用的所有内存页面?

Par*_*zie 5 memory security android

我是一名软件工程师,正在构建一个将由政府机构使用的 Android 应用程序。

我们合同中的一项要求是应用程序必须符合 FIPS 140。 https://en.wikipedia.org/wiki/FIPS_140

为了符合 FIPS,我们的应用程序必须在 android 应用程序关闭时将 RAM 中的所有密码对象归零并清除。(通过从 RAM 中清零和清除密码,我们减少了攻击者的机会窗口。即这减轻了冷启动攻击风险:https : //en.wikipedia.org/wiki/Cold_boot_attack

为了满足这一要求,我们最初遵循以下两个 SO 帖子中的建议将用户密码捕获为 CharArray 而不是字符串

//First collect the password from Edit Text as a []char
int pl = passwordEditText.length();
char[] password = new char[pl];
passwordEditText.getText().getChars(0, pl, password, 0);

//Now set the password on viewmodel
viewModel.setPassword(password) 
Run Code Online (Sandbox Code Playgroud)

获得密码后,我们使用它来调用第 3 方网络服务库,该库获取数据以显示在屏幕上。

视图模型伪代码:

public DataObject getData(char[] password){
     return this.webService.getData(password);
}
Run Code Online (Sandbox Code Playgroud)

当用户完成我们的应用程序时,我们调用以下方法将密码归零和清除

视图模型伪代码:

public zeroPassword(){
    Arrays.fill(this.password, 0);
    this.password = null;
}
Run Code Online (Sandbox Code Playgroud)

这一切都很好,因为 java 中的 char 数组是通过引用传递的(与不可变的字符串不同),并且我们在 zeroPassword 方法中有效地从内存中将密码字符数组的任何痕迹归零。

然而...

我们深入研究了第 3 方 WebService 代码(this.webService.getData(password)),结果发现在幕后,WebService 将字符数组密码转换为字符串,然后在进行网络调用之前将其传递。

基本上 - 即使我们将 Android ViewModel 代码中的 char 数组引用归零,因为 char 数组由第 3 方库获取并用于创建字符串,密码仍将存在于内存中:(

选项

在这一点上,我们正在考虑两种选择:

  1. 选项 1是获取第三方库的副本并对其进行修改,使其不适用于密码字符串。通过这种方式,我们可以更改任何密码字符串的用法以使用字符数组、缓冲区等 - 我们可以在某个时候将所有对象归零)
  2. 选项 2 - 当用户关闭应用程序时,我们研究了一些方法来归零和清除我们的 android 应用程序使用的所有内存页面(即关闭整个应用程序并清除 RAM)。

作为一个团队,我们更喜欢选项 2,因为它会覆盖我们所有的基地。选项 1 将具有挑战性、侵入性、耗时且混乱。

更新- 根据这里的答案,似乎选项 1 甚至不会实际工作如何确保在 Java 中销毁 String 对象? Java 使用分代垃圾收集,并到处复制对象,甚至是 char 数组,因此不能保证将 char 数组清零从 RAM 中删除密码。

有没有办法完成我们被要求做的事情?即从内存中完全擦除密码的任何痕迹?

android安全专家可以发表意见吗?

谢谢

Har*_*thy 0

根据ViewModel 文档

\n\n
\n

当所有者活动完成时,框架调用 ViewModel\n 对象的onCleared()方法,以便清理资源

\n
\n\n

你不需要手动创建/调用析构函数来清理ViewModel资源,因为这个生命周期组件已经有一个清理自己资源的机制。

\n\n

为了更容易理解,ViewModel 有以下行为:

\n\n
    \n
  • 当配置更改重新创建 Activity 时:我们仍然拥有相同的 ViewModel 实例。

  • \n
  • 当 Activity 完成时:ViewModel 将自动onCleared()为我们调用清理资源,因此我们甚至不需要手动取消绑定/清理。

  • \n
\n\n

某些 ViewModel 对象仍然存在于内存中的原因是因为 Activity(具有 ViewModel)仍然处于活动状态,或者可能有另一个类保存对此 Activity 的引用。

\n