Я инженер-программист, создающий приложение Android, которое будет использоваться государственным учреждением.
Одним из требований нашего контракта является то, что приложение должно соответствовать требованиям FIPS 140. https://en.wikipedia.org/wiki/FIPS_140
Для соответствия требованиям FIPS наше приложение должно обнулять и очищать любые объекты паролей в ОЗУ, когда приложение android закрыто. (Обнуляя и удаляя пароль из ОЗУ, мы сокращаем окно возможностей для злоумышленников. То есть это снижает риск атаки при «холодной» загрузке: 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 передаются по ссылке (в отличие от неизменяемых строк), и мы эффективно обнуляем любую трассировку. массива символов пароля из памяти в методе zeroPassword.
HOWEVER ...
Копаем в стороннем коде WebService ( this.webService. getData (пароль) ) и оказывается, что под прикрытием веб-служба преобразует пароль массива char в строку, а затем передает его перед выполнением сетевого вызова.
В основном - даже если мы обнулите ссылку на массив char в нашем Android коде ViewModel, поскольку массив char берется сторонней библиотекой и используется для создания строки, пароль все равно будет существовать в памяти: (
OPTIONS
На данный момент мы рассматриваем два варианта:
- Вариант 1 - получить копию сторонней библиотеки и изменить ее так, чтобы что он не работает со строками пароля. Таким образом, мы можем изменить любое использование строки пароля для использования массивов символов, буферов и т. Д. c - все объекты, которые мы можем обнулить в какой-то момент)
- Вариант 2 - Мы исследуем какой-то способ обнулить и очистить все страницы памяти, используемые нашим приложением android (т.е. закрыть все приложение и очистить ОЗУ), когда пользователь закрывает приложение.
Как команда, мы предпочитаем вариант 2, потому что он будет охватывать все наши базы. Вариант 1 будет сложным, инвазивным, трудоемким и грязным.
ОБНОВЛЕНИЕ - Исходя из приведенного здесь ответа, кажется, что Вариант 1 даже не работает Как я могу убедиться уничтожение объекта String в Java? Java использует сборку мусора поколений и копирует объекты повсеместно, даже массивы символов, поэтому обнуление массивов символов не гарантирует удаление пароля из ОЗУ.
Есть ли способ выполнить sh то, что нас попросили сделать? т.е. полностью стереть следы пароля из памяти?
Могут ли android эксперты по безопасности подсказать?
Спасибо