Содержание статьи
WARNING
У каждого гаджета с ОС Android есть свои существенные отличия — как в прошивке, так и на аппаратном уровне. Даже разные версии одной модели могут сильно отличаться. Карты памяти тоже имеют свои особенности. Поэтому детальные руководства по использованию шифрования на одном устройстве часто не работают без модификаций на другом. Универсальных методов здесь не существует. Есть лишь общие подходы, которые и описаны в данной статье.
Особая роль карты памяти
Изначально разработчики Android предполагали использование карты памяти только как отдельного хранилища пользовательских файлов. Это был просто склад мультимедиа без каких-либо требований к его защите и надежности. Карточки microSD(HC) с FAT32 вполне справлялись с ролью простейшей хранилки, освобождая внутреннюю память от фоток, видеороликов и музыки.
Возможность переносить на карту памяти не только мультимедийные файлы, но и приложения впервые появилась в Android 2.2 Froyo. Реализована она была с помощью концепции зашифрованных контейнеров на каждое приложение, но защищало это исключительно от попадания не в те руки карты — но не смартфона.
К тому же это была полумера: многие программы переносились частично, оставляя часть данных во внутренней памяти, а некоторые (например, системные или содержащие виджеты) не переносились на карточку вовсе. Сама возможность переноса приложений зависела от их типа (предустановленное или стороннее) и внутренней структуры. У одних каталог с пользовательскими данными сразу располагался отдельно, а у других — в подкаталоге самой программы.
Если приложения интенсивно использовали операции чтения/записи, то надежность и скорость работы карточек уже не могла удовлетворить разработчиков. Они намеренно делали так, что перенос программ штатными средствами становился невозможен. За счет такого ухищрения их творение гарантированно получало прописку во внутренней памяти с большим ресурсом перезаписи и высоким быстродействием.
С четвертой версии в Android появилась возможность выбрать, где разместить приложение. Можно было назначить карту памяти как диск для установки программ по умолчанию, но не все прошивки корректно поддерживали эту функцию. Как она работает в конкретном устройстве — удавалось выяснить лишь опытным путем.
В пятом Андроиде Google снова решила вернуть изначальную концепцию и сделала все, чтобы максимально затруднить перенос приложений на карту памяти. Крупные производители уловили сигнал и добавили в прошивки собственные функции мониторинга, определяющие попытки пользователя принудительно переместить приложения на карточку с использованием рута. Более-менее работал только вариант с созданием жестких или символьных ссылок. При этом приложение определялось по стандартному адресу во встроенной памяти, а фактически находилось на карточке. Однако путаницу вносили файловые менеджеры, многие из которых некорректно обрабатывали ссылки. Они показывали неверный объем свободного места, поскольку считали, что приложение якобы занимает место и во встроенной памяти, и на карточке одновременно.
Адаптируй это!
В Android Marshmallow появился компромисс под названием «Адаптируемое хранилище» — Adoptable Storage. Это попытка Google сделать так, чтобы и овцы остались целы, и солдаты удовлетворены.
Функция Adoptable Storage позволяет объединить пользовательский раздел во встроенной памяти с разделом на карточке в один логический том. Фактически она создает на карточке раздел ext4 или F2FS и добавляет его к пользовательскому разделу внутренней памяти. Это чисто логическая операция объединения, отдаленно напоминающая создание составного тома из нескольких физических дисков в Windows.
В процессе объединения с внутренней памятью карточка переформатируется. По умолчанию весь ее объем будет использован в объединенном томе. В таком случае файлы на карточке уже нельзя будет прочитать на другом устройстве — они будут зашифрованы уникальным ключом устройства, который хранится внутри доверенной среды исполнения.
В качестве альтернативы можно зарезервировать на карточке место под второй раздел с FAT32. Хранимые на нем файлы будут видны на всех устройствах, как прежде.
Способ разделения карточки задается либо через меню Adoptable Storage, либо через отладочный мост для Android (Android Debug Bridge — ADB). Последний вариант используется в тех случаях, когда производитель скрыл Adoptable Storage из меню, но не удалил эту функцию из прошивки. Например, она скрыта в Samsung Galaxy S7 и топовых смартфонах LG. В последнее время вообще появилась тенденция убирать Adoptable Storage из флагманских устройств. Она считается костылями для бюджетных смартфонов и планшетов, которые не комплектуются достаточным объемом встроенной Flash-памяти.
Впрочем, не маркетологам решать, как нам использовать свои устройства. Через ADB на компьютере с Windows функция Adoptable Storage включается следующим образом.
- Делаем бэкап всех данных на карточке — она будет переформатирована.
- Устанавливаем последнюю версию Java SE Development kit с сайта Oracle.
- Устанавливаем последнюю версию Android SDK Manager.
- Включаем на смартфоне отладку по USB.
- Запускаем SDK Manager и в командной строке пишем:
$ adb shell $ sm list-disks
- Записываем номер диска, под которым определяется карта памяти (обычно он выглядит как 179:160, 179:32 или подобным образом).
- Если хочешь добавить к внутренней памяти весь объем карточки, то пиши в командной строке:
$ sm partition disk: x:y private
где x:y — номер карты памяти.
- Если хочешь оставить часть для тома FAT32, то измени команду из п. 7 на такую:
$ sm partition disk:x:y mixed nn
где nn — остаток объема в процентах для тома FAT32.
Например, команда sm partition disk:179:32 mixed 20
добавит к встроенной памяти 80% объема карточки и оставит на ней том FAT32 в 1/5 ее объема.
На некоторых смартфонах этот метод в варианте «как есть» уже не работает и требует дополнительных ухищрений. Производители делают все, чтобы искусственно разделить свою продукцию по рыночным нишам. Топовые модели выпускаются с разным объемом встроенной памяти, и желающих переплачивать за него находится все меньше.
Некоторые смартфоны не имеют слота для карты памяти (например, серия Nexus), но поддерживают подключение USB-Flash-носителей в режиме OTG. В таком случае флешку также можно использовать для расширения объема встроенной памяти. Делается это следующей командой:
$ adb shell sm set-force-adoptable true
По умолчанию возможность использовать USB-OTG для создания адаптированного хранилища отключена, поскольку его неожиданное извлечение может привести к потере данных. Вероятность внезапного отключения карты памяти гораздо ниже из-за ее физического размещения внутри устройства.
Если с добавлением объема сменного носителя или его разбиением на разделы возникают проблемы, то сначала удали с него всю информацию о прежней логической разметке. Надежно это можно сделать с помощью линуксовой утилиты gparted
, которая на компьютере с Windows запускается с загрузочного диска или в виртуальной машине.
Согласно официальной политике Google приложения могут сразу быть установлены в адаптируемое хранилище или перенесены в него, если разработчик указал это в атрибуте android:installLocation
. Ирония в том, что далеко не все собственные приложения Google пока позволяют это делать. Каких-то практических лимитов у «адаптированного хранилища» в Android нет. Теоретический предел для Adoptable Storage составляет девять зеттабайт. Столько нет даже в дата-центрах, а уж карты памяти большего объема тем более не появятся в ближайшие годы.
Сама процедура шифрования при создании адаптированного хранилища выполняется с помощью dm-crypt
— того же модуля ядра Linux, которым производится полнодисковое шифрование встроенной памяти смартфона (см. предыдущую статью «Криптостойкие андроиды. Как работает полнодисковое и пофайловое шифрование в Android»). Используется алгоритм AES в режиме сцепления блоков шифртекста (CBC). Для каждого сектора генерируется отдельный вектор инициализации с солью (ESSIV). Длина свертки хеш-функции SHA составляет 256 бит, а самого ключа — 128 бит.
Такая реализация, хотя и уступает в надежности AES-XTS-256, работает гораздо быстрее и считается достаточно надежной для пользовательских устройств. Любопытный сосед вряд ли вскроет зашифрованное адаптированное хранилище за разумное время, а вот спецслужбы давно научились использовать недостатки схемы CBC. К тому же реально не все 128 бит ключа оказываются совершенно случайными. Невольное или намеренное ослабление встроенного генератора псевдослучайных чисел — самая часто встречающаяся проблема криптографии. Она затрагивает не столько гаджеты с Android, сколько все потребительские устройства в целом. Поэтому самый надежный способ обеспечения приватности — вообще не хранить конфиденциальные данные на смартфоне.
INFO
Если после объединения памяти с помощью Adoptable Storage выполнить сброс до заводских настроек, то данные на карточке также пропадут. Поэтому предварительно стоит сделать их бэкап, а лучше — сразу назначить облачную синхронизацию.
Альтернативное шифрование данных на карте памяти
Теперь, когда мы разобрались с особенностями хранения файлов на карте памяти в разных версиях Android, перейдем непосредственно к их шифрованию. Если у тебя девайс с шестым Андроидом и новее, то с большой вероятностью в нем так или иначе можно активировать функцию Adoptable Storage. Тогда все данные на карточке будут зашифрованы, как и во встроенной памяти. Открытыми останутся лишь файлы на дополнительном разделе FAT32, если ты захотел его создать при переформатировании карточки.
В более ранних выпусках Android все гораздо сложнее, поскольку до версии 5.0 криптографическая защита не затрагивала карты памяти вообще (за исключением данных перенесенных приложений, разумеется). «Обычные» файлы на карточке оставались открытыми. Чтобы закрыть их от посторонних глаз, понадобятся сторонние утилиты (которые часто оказываются лишь графической оболочкой для встроенных средств). При всем разнообразии существующих способов принципиально разных получается четыре:
- использование универсального криптоконтейнера — файла с образом зашифрованного тома в популярном формате, с которым умеют работать приложения для разных ОС;
- прозрачное шифрование файлов в указанном каталоге через драйвер FUSE и стороннюю утилиту для создания/монтирования зашифрованного раздела в виде файла;
- шифрование всей карты памяти через dm-crypt;
- использование «черного ящика» — отдельного приложения, которое хранит зашифрованные данные в собственном формате и не предоставляет доступ к ним для сторонних программ.
Первый вариант хорошо знаком всем, кто пользуется TrueCrypt или одним из его форков на компьютере. Для Android есть приложения с поддержкой контейнеров TrueCrypt, но ограничения у них разные.
Второй вариант позволяет организовать «прозрачное шифрование», то есть хранить все данные зашифрованными и расшифровывать их при обращении из любого приложения. Для этого все данные из выбранного каталога представляются как содержимое виртуальной файловой системы с поддержкой шифрования на лету. Обычно используется EncFS, подробнее о которой мы поговорим ниже.
Третий вариант — встроенный dm-crypt. Использовать его можно, к примеру, через LUKS Manager. Приложению требуется рут и установленный BusyBox. Интерфейс у него — на любителя.
LUKS Manager создает на карточке криптоконтейнер в виде файла. Этот контейнер можно подключить к произвольному каталогу и работать с ним, как с обычным. Плюс в том, что у этого решения есть кросс-платформенная поддержка. Работать с контейнером можно не только на гаджете с Android, но и на десктопе: в Linux — через cryptsetup, а в Windows — через программу FreeOTFE или ее форк LibreCrypt. Минус — неудобство использования совместно с облачными сервисами. Каждый раз в облаке приходится повторно сохранять весь контейнер, даже если изменился один байт.
Четвертый вариант в целом малоинтересен, поскольку сильно ограничивает сценарии использования зашифрованных файлов. Их можно будет открыть только каким-то специализированным приложением и уповать на то, что его разработчик преуспел в изучении криптографии. К сожалению, большинство таких приложений не выдерживает никакой критики. Многие из них вообще не имеют никакого отношения к криптографии, поскольку просто маскируют файлы вместо того, чтобы шифровать их. При этом в описании могут упоминаться стойкие алгоритмы (AES, 3DES...) и приводиться цитаты из «Прикладной криптографии» Шнайера. В лучшем случае у таких программ будет очень плохая реализация шифрования, а в худшем его не будет вовсе.
Рассмотрим для примера Private Photo Vault. Приложение для сокрытия приватных фоток позволяет ограничивать к ним доступ только с использованием четырехзначных пинов.
Свертку от них (хеш SHA-160) приложение хранит в своем файле настроек com.enchantedcloud.photovault_preferences.xml
. Чтобы найти пару хеш — пин, достаточно сгенерировать список хешей SHA-160 для 10 тысяч комбинаций пин-кодов (от 0000 до 9999). Среди них гарантированно найдется тот, который совпадает с записанным в .xml.
Можно поступить еще проще и банально загуглить хранимый в настройках хеш. Таких таблиц в интернете полно, и многие из них проиндексированы поисковиками — см. статью «Большой парольный коллайдер» в #194 номере. Например, по запросу C4B5C86BD577DA3D93FEA7C89CBA61C78B48E589
ты увидишь десятки ссылок с исходным значением 0123 — это и будет пин-код в Private Photo Vault.
Отсутствие шифрования лучше иллюзии криптозащиты. Подобных программ очень много, и доверять им вслепую нет никаких оснований. Внешний аудит они не проходили, поэтому фактически у нас остаются три перечисленных выше варианта: контейнер (TrueCrypt/VeraCrypt), EncFS и dm-crypt.
Криптоконтейнеры
Бесплатный менеджер криптоконтейнеров TrueCrypt подвергался проверке независимых специалистов много раз. Последний аудит не выявил в нем программных закладок — лишь пару уязвимостей: реализация AES оказалась восприимчива к атаке по времени за счет обращений к кешу, а функция CryptAcquireContext (используемая в вызовах CryptoAPI для получения дескриптора определенного ключевого контейнера) возвращает необрабатываемое ошибочное значение в некоторых нестандартных ситуациях. Обе уязвимости представляют скорее академический, нежели практический интерес. Однако проект заброшен, поэтому есть смысл посмотреть на другие форки, основанные на коде TrueCrypt v.7.1a, в частности VeraCrypt.
Официального клиента под Android для VeraCrypt нет и не планируется, однако его авторы рекомендуют использовать приложение EDS (Encrypted Data Store). Это российская разработка, существующая в полнофункциональном и облегченном варианте. Полная версия EDS стоит 329 рублей. Она поддерживает криптоконтейнеры формата TrueCrypt, VeraCrypt, CyberSafe, а также LUKS и EncFS. Умеет работать с локальными, сетевыми и облачными хранилищами, обеспечивая другим приложениям прозрачное шифрование. Шифрование на лету требует поддержки ядром ОС фреймворка FUSE и прав рут. Обычная работа с криптоконтейнерами возможна на любых прошивках.
Версия EDS Lite распространяется бесплатно и имеет функциональные ограничения. Например, она может работать исключительно с контейнерами, содержащими внутри том с файловой системой FAT, зашифрованной по алгоритму AES c длиной ключа 256 бит и с использованием хеш-функции SHA-512. Другие варианты ею не поддерживаются. Поэтому стоит ориентироваться на платную версию.
Криптоконтейнер — самый надежный и универсальный способ. Его можно хранить в любой файловой системе (хоть FAT32) и использовать на любом устройстве. Все данные, которые ты зашифровал на десктопе, станут доступными на смартфоне, и наоборот.
EncFS
В 2003 году Валиент Гоф (Valient Gough — инженер-программист из Сиэтла, писавший софт для NASA, а позже работавший на Google и Amazon) выпустил первый релиз свободной файловой системы со встроенным механизмом прозрачного шифрования — EncFS. Она взаимодействует с ядром ОС благодаря слою обратного вызова, получая запросы через интерфейс libfuse фреймворка FUSE. По выбору пользователя EncFS использует один из симметричных алгоритмов, реализованных в библиотеке OpenSSL, — AES и Blowfish.
Поскольку в EncFS используется принцип создания виртуальной файловой системы, для нее не потребуется отдельного раздела. В ОС Android достаточно установить приложение с поддержкой EncFS и просто указать ему пару каталогов. Один из них будет хранить зашифрованное содержимое (пусть он называется vault), а второй — временно расшифрованные файлы (назовем его open).
После ввода пароля файлы считываются из каталога vault и сохраняются расшифрованными в open (как в новой точке монтирования), где доступны всем приложениям. После окончания работы жмем в приложении кнопку Forget Decryption (или ее аналог). Каталог open размонтируется, а все расшифрованные файлы из него исчезнут.
Недостатки: EncFS не поддерживает жесткие ссылки, так как данные имеют привязку не к inode, а к имени файла. По этой же причине поддерживаются имена файлов длиной до 190 байт. В каталоге vault будут скрыты имена файлов и их содержимое, но останутся доступными метаданные. Можно узнать число зашифрованных файлов, их разрешения, последнее время доступа или модификации. Также существует явный признак использования EncFS — это файл настроек с префиксом encfs и указанием номера версии в его названии. Внутри файла записаны параметры шифрования, включая алгоритм, длину ключа и размер блоков.
Платный аудит EncFS был выполнен в феврале 2014 года. В его заключении говорится, что «EncFS, вероятно, надежна до тех пор, пока атакующая сторона имеет только один набор зашифрованных файлов и ничего более». Если же атакующему доступно больше данных (например, два снапшота файловой системы, снятые в разное время), то EncFS не может считаться надежной.
После установки EncFS будет видна как отдельная файловая система пространства пользователя через драйвер FUSE. Доступ к ней будет реализован через какое-то стороннее приложение — например, файловый менеджер Encdroid или Cryptonite. Последний базируется на исходном коде EncFS, поэтому остановимся на нем.
Cryptonite
Последняя версия приложения Cryptonite — 0.7.17 бета от 15 марта 2015 года. Ее можно установить на любое устройство с Android 4.1 и выше, однако часть функций работает более стабильно в Android 4.3 и более свежих версиях.
Большинство операций в Cryptonite не требуют root и каких-то специфических компонентов. Создание томов EncFS и синхронизация с Dropbox может выполняться как на официальных, так и на кастомных прошивках.
Однако для ряда операций потребуется монтирование томов EncFS, для чего нужны права root и поддержка фреймворка FUSE ядром ОС. Использование FUSE необходимо для организации «прозрачного шифрования», то есть для того, чтобы другие приложения имели возможность обращаться к зашифрованным данным и получать их уже расшифрованными. В большинстве старых прошивок поддержка FUSE отсутствует, но она есть в CyanogenMod, MIUI, AOKP и других кастомных. Начиная с Android 4.4 FUSE штатно используется для эмуляции SD-карты во встроенной памяти.
Недостатки: при нажатии «Расшифровать» и успешном вводе пароля Cryptonite создает временную копию дешифрованного файла в /data/data/csh.cryptonite/app_open/. Копия файла помечается как world readable (читаемая и исполняемая для всех). Удалить расшифрованные файлы можно нажатием кнопки Forget Decryption.
Выводы
Способ шифрования данных на карте памяти стоит выбирать, исходя из двух основных критериев: сценария использования и версии Android. На современных гаджетах с Android 6.0 и выше самый простой вариант — воспользоваться Adoptable Storage, присоединить карточку к внутренней памяти и выполнить прозрачное шифрование всего логического тома. Если надо сделать файлы доступными на других устройствах или добавить шифрование данных на карточке в старых девайсах — подойдут криптоконтейнеры проверенных форматов. Сторонних утилит по типу «вещь в себе» лучше избегать вовсе, поскольку вместо реальной защиты данных они часто лишь имитируют ее.