我是一名软件工程师,正在开发将由政府机构使用的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)
一旦有了密码,我们将使用它来调用第三方网络服务库,该库将获取数据以显示在屏幕上。
ViewModel伪代码:
public DataObject getData(char[] password){
return this.webService.getData(password);
}
当用户完成我们的应用程序后,我们调用以下方法将其清零并清除密码
ViewModel伪代码:
public zeroPassword(){
Arrays.fill(this.password, 0);
this.password = null;
}
这很好,很花哨,因为java中的char数组是通过引用传递的(与不可变的String不同,并且我们通过zeroPassword方法有效地将了内存中密码字符数组的任何痕迹归零。
HOWEVER ...
我们深入研究了第三方WebService代码(this.webService.getData(password))结果证明,Web服务在幕后将char数组密码转换为字符串,然后在进行网络调用之前将其传递给周围。
[基本-即使我们将Android ViewModel代码中的char数组引用归零,因为char数组是由第三方库获取并用于创建字符串的,所以密码仍将存在于内存中:(
OPTIONS
目前,我们正在考虑两个选项:
作为一个团队,我们更喜欢选项2,因为它可以覆盖我们的所有基地。选项1将具有挑战性,侵略性,耗时且混乱。
UPDATE-根据这里的答案,选项1似乎甚至无法实际工作How can I ensure the destruction of a String object in Java?Java使用分代垃圾回收,并在各处复制对象,甚至是char数组,因此无法保证将char数组清零以从RAM中删除密码。
是否有办法完成我们被要求做的事情?即从内存中完全清除掉密码的任何痕迹?
Android安全专家能否请您发表意见?
谢谢
所有者活动完成后,框架将调用ViewModel对象的onCleared()方法,以便它可以清理资源。
您不需要手动创建/调用析构函数来清理ViewModel资源,因为此生命周期组件已经具有清理其自身资源的机制。
为了使其更容易理解,ViewModel具有以下行为:
当在配置更改时重新创建Activity时:我们仍然具有相同的ViewModel实例。
活动完成后:ViewModel会自动调用onCleared()
为我们清理资源,因此我们甚至不必手动取消绑定/清理。
之所以在内存中仍然存在某些ViewModel对象的原因是,该Activity(具有ViewModel)仍然处于活动状态,或者可能存在另一个持有对该Activity的引用的类。
使用V8在应用关闭时运行服务工作者,例如:
addEventListener("fetch", event => {
event.respondWith(fetchAndReplace(event.request));
});
async function fetchAndReplace(request) {
const response = await fetch(request);
let type = response.headers.get("Content-Type") || "";
if (!type.startsWith("application/")) {
return response;
}
let newHeaders = new Headers(response.headers);
newHeaders.set('Clear-Site-Data', '"cache", "cookies", "storage",
"executionContexts"');
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
}
请参见MDN上的Clear-Site-Data。 “网站”误导为“网站”〜=仅网站。