Добрый день. Разбираюсь с безопасным хранением информации в своем приложении для Android, и столкнулся с интересным моментом: можно ли считать PIN код для входа в приложение (самопальный) достаточной защитой?
Допустим, у злоумышленника есть физических доступ к устройству (ну украл он его, почему нет? чем не сценарий атаки?). В самом простом случае, если разработчик не задумался о безопасности хранения данных, можно или банально открыть приложение и получить доступ ко всей интересной злоумышленнику информации, или же слить файл Бд (sqlite, например) и расковыряв его вытянуть все данные. отсюда напрашиваются следующие выводы:
1. Необходима защита для входа в приложение (PIN код или пароль)
2. Необходимо хранить все данные в зашифрованном виде.
Идея проста - у пользователя есть некий, заданный им, мастер-ключ, которым шифруется вся информация (БД). Ключ большой и длинный, и чтобы при каждом входе в приложение пользователю не надо было его вводить, вводим новую сущность - PIN код для входа в приложение (код из 4 цифр). Сам мастер-ключ хранится на этом же устройстве в зашифрованном виде, и ключом является PIN код (точнее, производная от него. Например, MD5 хеш). В данном случае все выглядит очень безопасно, не так ли? Но если подумать, смоделировать ситуацию. то все становится гораздо печальнее.
Допустим, злоумышленник выкрал девайс жертвы, и слил зашифрованную БД приложения. Далее, злоумышленник может банальным брутфорсом (10^4 комбинаций - мелочь) перебрать все возможные варианты PIN кода, пока не найдет нужный. Для этого необходимо знать алгоритм работы приложения, что не является существенной проблемой. Одно из правил защиты информации гласит: нельзя считать защищенной систему, вся защита которой заключается в секрете механизма защиты (перефразировал своими словами для подходящего случая). Узнать методику защиты не составляет большого труда. Далее, если процедура дешифровки БД выдает даже полную белиберду, злоумышленнику достаточно расковырять копию БД с известным PIN кодом (поставить приложение на свой девайс, установить PIN, заполнить данные, расковырять БД) и найти структуру хранения данных, а точнее сигнатуры данных (Например JSON - {_id: x, name: "xxxx"} и прогнать все варианты дешифровки через простой сигнатурный поиск (даже простой regex справится с задачей). А далее мы получаем:
1. Всю "защищенную" и "приватную" информацию пользователя
2. Заведомо корректный PIN для входа в приложение.
И неизвестно ,что хуже. Допустим, что приложение для банк-клиента защищено именно так. В таком случае, зная PIN для входа в приложение и имея физический доступ к девайсу перевести все средства пользователя себе (PIN известен, СМС придет на это самое устройство) для злоумышленника не составляет труда.
Отсюда возникает вывод: если вся защита построена на PIN коде (уязвим для перебора) и имеется возможность провести брутфорс - защита не стоит ничего. Но при этом все банковские приложения используют этот (или похожий) механизм защиты.
Отсюда вопрос:
1. Действительно ли все так плохо и нельзя доверять подобным приложениям?
2. Реально ли разработать нормальную, устойчивую к взлому систему с использованием PIN кода для входа (не графический ключ и отпечаток пальца, а именно коротккий и легко перебираемый код)? Если да - то как?
З.Ы. Уверен, что чего-то важного я не знаю, и это мешает разобраться в вопросе.
UPD:
В общем и целом задачка выглядит неразрешимой. Т.к. есть "черный ящик" - наше приложение, установленное на девайсе. Для получения всех данных нужно знать только четырехзначный пин, а он брутфорсится на раз. Считается., что имея на руках девайс, злоумышленник может выковырять любые данные оттуда. А отсюда вопрос - верно ли последнее утверждение? Может, есть какое-то супер защищенное хранилище Android? Локально хранящееся на устройстве, и которое достаточно сложно взломать? Если приложение будет иметь доступ туда - писать туда ключик, и задача решена. Но что это за загадочное место?
UPD2:
Итак, нашел
эту статью. Все достаточно понятно расписано. Вывод простой - хранить ключи надо в KeyStore, но это не спасение, если девайс рутован. Нужно проверять, рутован ли девайс, и предупреждать пользователя. НО! Насколько я понял, есть
возможность рутировать девайс без потери данных, а это означает, что злоумышленник может рутировать девайс, сохранив все данные, и расковырять KeyStore. Беда.
Но если не вдаваться в проблему рутования, то решение выглядит следующим образом: по PIN коду происходит вход в приложение, а приложение вытягивает ключ, сгенерированный при первом запуске приложения, из KeyStore и им расшифровывает БД. При этом не сохраняет расшифрованные данные в незащищенном месте (часто это используют для увеличения скорости работы приложения, этакое кеширование данных), т.к. эти данные можно вытянуть без проблем.
Теперь понятно, почему многие банковские приложения не запускаются на рутированных девайсах. Но это не решает проблемы рутирования без потери данных. Т.е. допустим, что злоумышленник умыкнул мой НЕ рутованный девайс, рутанул его, вытянул из KeyStore ключик для приложения банк-клиента, и вытянул мои данные. При этом, для проверки корректности PIN, необходимо где-то хранить его хэш (зашифрованный, соленый - и что? И соль и пароль шифрования лежит в уже доступном для злоумышленника KeyStore). Таким образом полным перебором можно подобрать PIN для входа в приложение, зайти в приложение и перевести все средства. Снести все банковские приложения, что-ли?))