I'm a software engineer building an Android App that will be used by a government agency.
One requirement in our contract is that the app must be FIPS 140 compliant. https://en.wikipedia.org/wiki/FIPS_140
To be FIPS compliant our app must zeroize and clear any password objects in RAM, when the android app is closed. (By zeroing and clearing the password from RAM, we reduce the window of opportunity for attackers. i.e. this mitigates cold-boot attack risk: https://en.wikipedia.org/wiki/Cold_boot_attack)
To satisfy this requirement, we initially followed the advice in the following two SO posts to capture the user password as a CharArray instead of a string
- Why is char[] preferred over String for passwords?
- Getting a char array from the user without using a String
//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)
Once we have the password, we use it to call a 3rd party webservice library that fetches data for display on the screen.
ViewModel pseudocode:
public DataObject getData(char[] password){
return this.webService.getData(password);
}
When the user is done with our app, we call the following method to zeroize and clear the password
ViewModel pseudocode:
public zeroPassword(){
Arrays.fill(this.password, 0);
this.password = null;
}
This is all fine and dandy because char arrays in java are passed by reference (unlike Strings that are immutable), and we effectively zeroize any trace of the password character array from memory in the zeroPassword method.
HOWEVER...
We dug into the 3rd party WebService code (this.webService.getData(password)) and it turns out that under the covers, the webservice converts the char array password into a string, and then passes it around before making a network call.
Basically - Even though we zeroize the char array reference in our Android ViewModel code, because the char array is taken by a 3rd party lib and used to create a string, the Password will still exist in memory :(
OPTIONS
At this point we're considering two options:
- Option 1 is to get a copy of the third party library and modify it so that it doesn't work with password strings. This way we can change any password string usage to use char arrays, buffers etc - all objects that we can zeroize at some point)
- Option 2 - We investigate some way to zeroize and clear all memory pages used by our android app (i.e. shut down the whole app and clear RAM), when the user closes the app.
As a team we prefer option 2 because it would cover all of our bases. Option 1 will be challenging, invasive, time consuming, and messy.
UPDATE - Based on the answer here, it seems like Option 1 wont even actually work How can I ensure the destruction of a String object in Java? Java uses generational garbage collection, and copies objects all over the place, even char arrays, so zeroing char arrays isn't guaranteed to remove the password from RAM.
Is there a way to accomplish what we've been asked to do? i.e. fully wipe any trace of the password from memory?
Can android security experts please opine?
Thanks