|
|
|||||||||||||||||||||||||||||
|
Шифрование данных в мобильных приложенияхИсточник: IBM developerWorks Россия Джон Мачов
Перед началом работыО данном руководствеЗабота о безопасности существует всегда, поэтому в программном обеспечении нужно учитывать необходимость защиты конфиденциальных данных. Мобильные приложения не являются неуязвимыми. Фактически, мобильные устройства и их программное обеспечение имеют особенность, заключающуюся в том, что большинство людей носит свои устройства с собой постоянно. В данном руководстве представлен обзор шифрования данных в Java 2 Micro Edition J2ME-приложении (Java 2 Micro Edition) (MIDlet). Руководство начинается с краткого введения в шифрование данных. Шифрование - это тема не для слабых духом; данный раздел довольно краток и посвящен, в основном, API шифрования с открытым исходным кодом, написанным Legion of Bouncy Castle. Тема завершается разработкой мидлета (MIDlet), демонстрирующего шифрование и дешифрование текстовых строк. Одной проблемой, присущей большинству мобильных устройств, является ограниченный объем памяти. Хотя Bouncy Castle и другие библиотеки шифрования предлагают богатую функциональность, существует также ее цена. Как и в большинстве используемых вами библиотеках, только небольшие фрагменты кода обычно нужны вашему приложению. Одним из традиционных способов удаления неиспользуемого кода, одновременно делая приложение более трудным для обратного анализа, является использование Java-обфускатора (obfuscator - компонент, выполняющий процедуру засекречивания class-файлов Java). Я познакомлю вас с обфускатором с открытым исходным кодом - ProGuard. Мы рассмотрим все, начиная с загрузки и установки и заканчивая конфигурированием J2ME Wireless Toolkit для использования ProGuard. В завершающем разделе данного руководства сравниваются размеры JAR-файла засекреченного (obfuscating) мидлета с обычным мидлетом. Предварительные требованияДля запуска примеров этого руководства вам необходимо следующее программное обеспечение:
Требуемое программное обеспечениеУстановка программного обеспеченияВо время работы с данным руководством вы будете использовать четыре программных средства. Начнем с загрузки каждого из необходимых компонентов.
Установка JDK и Wireless ToolkitДля установки JDK используйте документацию по JDK. Вы можете выбрать либо каталог по умолчанию, либо указать другой каталог. Если вы выбрали другой каталог, запомните его. Во время установки Wireless Toolkit программа попытается обнаружить Java Virtual Machine (JVM); если она не сможет найти JVM, появится запрос на ввод пути установки JDK. The Wireless Toolkit (WTK) Wireless Toolkit содержится в одном исполняемом файле. Запустите этот файл для начала процесса установки. Рекомендуется использовать каталог по умолчанию. Однако если вы используете другой каталог, выбранный вами путь не должен содержать пробелы. В конце каждой темы я рассмотрю, как настроить Wireless toolkit для Bouncy Castle и ProGuard. ШифрованиеОбзорПосле выхода MIDP 2.0 поддержка HTTPS теперь требуется во всех реализации MIDP. Однако, даже с выходом новой спецификации, пройдет некоторое время, пока устройства, поддерживающие MIDP 2.0, станут повсеместны. Кроме того, если шифрование данных необходимо вам в самом мобильном устройстве (а не как часть сетевого взаимодействия между устройством и удаленной системой), поддержки HTTPS недостаточно. В данном разделе рассмотрены некоторые основы того, почему шифрование важно для мобильных приложений, и приведено краткое введение в Bouncy Castle, API для шифрования и дешифрования данных с открытым исходным кодом. Я завершу этот раздел описанием шагов по установке Bouncy Castle, что подготовит нас к следующему разделу, в котором мы напишем мидлет, способный шифровать и дешифровать простые текстовые строки.
Почему важно шифрованиеВместе с распространением и портативностью мобильных устройств возник уникальный набор вопросов по безопасности. Многие люди носят мобильные телефоны. По мере того, как устройства становятся все более умелыми, предлагая доступ к корпоративной электронной почте, базам данных и другой корпоративной информации, вопрос, как защитить эту информацию, становится приоритетным. Если устройство будет похищено или утеряно, появится риск компрометации конфиденциальных данных. Это относится не только к данным, находящимся на устройстве, но и к приложениям, которые предоставляют доступ к данным на удаленном сервере. Кроме того, взаимодействие по беспроводной сети с использованием мобильного устройства формирует свой собственный набор присущих ему рисков. Обладая знаниями и оборудованием, можно перехватить данные почти повсюду между вашим устройством и оконечной точкой вашего взаимодействия. Хотя предметом рассмотрения в данном руководстве является, главным образом, шифрование данных на мобильных устройствах, важно понимать, что это только один шаг в обеспечении конфиденциальности.
КлючиТак же как обычный ключ позволяет вам закрывать и открывать двери вашего дома, термин ключ (key) при обсуждении шифрования имеет такую же аналогию - закрытие, или шифрование, данных для ограничения доступа, и открытие, или дешифровка, данных для разрешения доступа. В мире шифрования ключ - это ничто иное, как набор символов или цифр, используемых во время процессов шифрования и дешифрования. Вы узнаете о ключах подробнее при обсуждении шифров.
ШифрыШифр - это способ преобразования конфиденциальной информации в зашифрованный формат. Для данного обсуждения представляйте шифр ни чем иным, как алгоритмом. Так же как существует большое число алгоритмов сортировки данных в компьютере (пузырьковая сортировка, быстрая сортировка и т.д.), существует много алгоритмов для шифрования и дешифрования данных. Типы шифровШифры могут быть симметричными или асимметричными. Симметричные шифры используют один и тот же ключ для шифрования и дешифрования данных, и часто называются системами с секретным ключом. То есть, значение ключа хранится в секрете двумя участниками - тем, кто шифрует данные, и тем, кто дешифрует их. В асимметричных шифрах используются два различных ключа: один для шифрования и один для дешифрования. Такие системы называются системами с открытым ключом , что означает общедоступность ключа для шифрования данных. Иначе говоря, каждый имеет доступ к ключу для шифрования информации, но только имеющий закрытый ключ может дешифровать данные.
АлгоритмыСуществует большая путаница, связанная с шифрованием. Это касается и выбора алгоритма, часто называемого механизмом (engine). Существует масса доступных алгоритмов, вот лишь несколько из них:
Ни один алгоритм не является наилучшим. Некоторые взломаны, тогда как другие были заменены более эффективными алгоритмами. Решение о том, какой алгоритм использовать - это не точная наука. Я бы рекомендовал поработать с данным руководством, для того чтобы узнать, как использовать шифрование в мидлете с применением Bouncy Castle. После освоения основ процесса вы можете исследовать различные алгоритмы и решить, какой является наилучшим для требований вашего приложения.
Обзор Bouncy CastleBouncy Castle - это Java API для шифрования и дешифрования данных с открытым исходным кодом. Bouncy Castle является провайдером Java Cryptography Extension (JCE). JCE - это необязательный пакет, обеспечивающий поддержку шифров, ключей и аутентификацию сообщений в Java 2 Platform, Standard Edition (J2SE). По существу, провайдер предлагает один или несколько алгоритмов для шифрования и дешифрования данных. На сегодняшний день Bouncy Castle поддерживает более 20 механизмов. Это звучит хорошо, поскольку обеспечивается большая гибкость в способе шифрования данных. С другой стороны, приходится платить объемом кода: Bouncy Castle занимает свыше 900 KB. К счастью, только часть API используется в один и тот же момент времени. И, как вы увидите дальше в этом руководстве, я удалю все классы, методы и поля, которые не нужны для использования шифратора.
Установка Bouncy CastleДля добавления поддержки Bouncy Castle во все приложения, разрабатываемые в WTK, разархивируйте файл midp_classes.zip в каталоге C:\WTK21\apps\lib. Если вы хотите ограничить использование библиотеки Bouncy Castle и добавить ее поддержку только для конкретного проекта, разархивируйте ZIP-файл в каталог \lib вашего проекта. Например, если бы вы создали проект EncryptTest, то должны были бы разархивировать файл midp_classes.zip в каталог C:\WTK21\apps\EncryptTest\lib. После помещения Bouncy ZIP-файла в нужное место, вы можете добавить необходимые выражения import для любых классов, выбранных для использования в вашем мидлете. WTK найдет class-файлы и включит их в ваш пакетированный мидлет.
Резюме по разделуВ данном разделе было рассмотрено шифрование и причины, почему оно является важным при разработке мобильных приложений. Были рассмотрены также некоторые ключевые концепции шифрования, такие как шифры и ключи, и перечислено несколько хорошо известных алгоритмов шифрования. Я завершил раздел обзором Bouncy Castle API с открытым исходным кодом с последующим кратким описанием процесса его установки. Теперь вы узнаете о том, как использовать Bouncy Castle API в мидлете. Мидлет EncryptTextОсновные этапы шифрованияСуществует много алгоритмов, стандартов и процессов для защиты данных. Моя цель заключается не в подробном обсуждении шифрования, а в демонстрации нескольких простых шагов для обеспечения элементарного шифрования в мидлете. Вы должны понимать, что для хорошей защиты ваших приложений вам понадобится намного более трудоемкая и хорошо спланированная работа. Данный обзор приведен просто для того, чтобы вы начали работу, и демонстрирует стандартный способ шифрования информации. Для шифрования текстовой строки я буду выполнять следующие действия:
Как вы можете догадаться, дешифрование данных - это аналогичный процесс:
Представляя в памяти эту общую картину, я напишу мидлет, чтобы продемонстрировать использование Bouncy Castle API.
Обзор мидлета: запрос текстаЛучшим способом узнать, как шифровать данные при помощи Bouncy Castle, является создание мидлета для демонстрации основ. Этот пример будет отображать TextBox для ввода пользователем строки для шифрования. Здесь будет три варианта меню: Encrypt, Decrypt и Exit. Далее приведено несколько иллюстраций, которые показывают, как выглядит мидлет в эмуляторе WTK. На рисунке 1 показан мидлет и TextBox , который будет содержать текст для шифрования/дешифрования. Рисунок 1. Запрос текста
Обзор мидлета: шифрование текстаПосле ввода текста выберите в меню вариант Encrypt . Текст будет пропущен через шифрующий механизм Bouncy Castle, а затем TextBox будет обновлен зашифрованным текстом. На рисунке 2 показаны эти два шага. Рисунок 2. Шифрование текста
Обзор мидлета: дешифрование текстаПоследним шагом является дешифрование содержимого TextBox обратно в оригинальную строку. На рисунке 3 показан выбор Decrypt из меню вместе с полученным текстом, помещенным назад в TextBox . Рисунок 3. Дешифрование текста
Создание мидлетаНиже перечислены шаги, которым я следовал при создании мидлета в WTK:
В следующем разделе показано, как начать создание нового проекта.
Создание проекта
Рисунок 4. Создание проекта EncryptText
Написание Java-кодаДля данного мидлета имеется один файл с Java-кодом: EncryptText.java. Скопируйте следующий код
При создании нового проекта WTK создает правильную структуру каталогов за вас. В данном примере WTK создал каталог C:\WTK21\apps\EncryptText и необходимые подкаталоги. Сохраните ваш Java-файл с исходным кодом как EncryptText.java в каталог src, как показано на рисунке 5 (обратите внимание на то, что названия диска и каталога WTK могут отличаться в зависимости от того, куда вы установили этот пакет инструментальных программ). Рисунок 5. Сохранение кода EncrpytText
Примечание: В следующих разделах Java-код будет показан детально.
Сохранение, компилирование и предварительная проверкаВыберите Build для компилирования, предварительной проверки и пакетирования мидлета, как показано на рисунке 6. Рисунок 6. Компоновка проекта EncryptText Выберите Run для запуска Application Manager.
Запуск мидлета EncryptTextДля запуска мидлета EncryptText выберите Launch, как показано на рисунке 7. Рисунок 7. Запуск мидлета EncryptText Изображение в левой части рисунка 8 показывает оригинальный текст, который будет шифроваться, и вариант меню для начала процесса шифрования. Изображение справа показывает текст в его зашифрованной форме. Рисунок 8. Шифрование текста В левой части рисунка 9 находится зашифрованный текст и вариант меню для начала процесса дешифрования. Изображение справа показывает результаты после завершения дешифрования. Рисунок 9. Дешифрование текста
Обзор кода: конструкторЯ начинаю с определения команд для обработки событий и TextBox для ввода текста пользователем. Последним шагом является создание экземпляра шифра. Хотя существует много механизмов шифрования, доступных в Bouncy Castle, для этого мидлета я выбрал механизм IDEA (International Data Encryption Algorithm).
Процесс шифрования, который я выбрал, будет обрабатывать блоки текста, то есть, последовательность битов шифруется как один блок, а ключ применяется к блоку в целом.
Для шифрования и дешифрования текста будет использоваться шифр (cipher), что я вскоре продемонстрирую. Последний вызов в конструкторе - распределение памяти для ключа. IDEA является симметричным шифром, это означает, что для шифрования и дешифрования данных используется один и тот же ключ.
Обзор кода: event handlingДля этого мидлета существует небольшая обработка событий для управления. Я вызываю соответствующий метод на основе выбранного пользователем варианта.
Обзор кода: шифрование данныхЯ начал процесс шифрования с записи введенных пользователем символов (в текстовом поле) в байтовый массив inBytes . Следующим шагом является инициализация шифра, который был распределен ранее. Первым параметром метода
Код внутри блока
Обзор кода: decrypt dataАналогично шифрованию, при дешифровании я начинаю с записи содержимого TextBox в массив. Я инициализирую шифр, передавая в этот раз, в качестве первого параметра, значение
Я завершаю процесс дешифрования обновлением TextBox новыми дешифрованными данными.
Резюме по разделуВ этом разделе мы работали с API шифрования Bouncy Castle. Я начал с простого дизайна мидлета (ничего, кроме TextBox): запрос строки для шифрования и три команды управления - для шифрования, для дешифрования и для выхода из мидлета. После этого я создал новый проект в WTK, написал Java-код, скомпилировал его и выполнил предварительную проверку мидлета. Последними действиями были детальный обзор исходного кода, обзор подробностей обработки данных с использованием Bouncy Castle. Закончив мидлет, я перехожу к теме засекречивания. ЗасекречиваниеОбзорПри работе с мобильными устройствами размер приложения чрезвычайно важен. Показав, как включить Bouncy Castle API в J2ME-приложение, я, в то же время, добавил значительный объем кода. Многие из современных мобильных устройств просто не смогли бы загрузить мидлет из-за ограниченной памяти. Вот где приходит на помощь засекречивание (obfuscation). В данном разделе я начну с краткого обзора засекречивания: что это такое, как оно помогает в уменьшении размера приложения и почему оно является важным. Я также приведу шаги по настройке обфускатора ProGuard для использования в WTK. Наконец, я покажу, как активизировать ProGuard и начать процесс генерирования засекреченных class-файлов.
Что такое засекречиваниеОбратный анализ Java-программ не является трудным процессом. Собственно говоря, существуют бесплатные декомпиляторы, которые делают работу за вас. Чтобы создать немного больше трудностей для приложений обратного анализа, многие Java-программисты используют так называемые обфускаторы для переименования классов, методов и полей. Назначение такого процесса переименования - сделать исходный код нечитаемым. Побочным эффектом процесса засекречивания является уменьшение размера class-файлов. Это достигается двумя шагами. Во-первых, может быть сэкономлено неожиданное количество байт при замене имен классов, методов и полей именами, состоящими из одного или двух символов. Кроме того, обфускаторы удаляют неиспользуемые классы, методы и поля. Комбинирование этих двух шагов может значительно уменьшить размер окончательного приложения. В следующем разделе я выполню сравнение мидлетов с засекречиванием и без него, чтобы дать вам почувствовать, ради чего я потратил столько времени на разговоры об этом.
Установка ProGuardWTK имеет встроенную среду для поддержки обфускаторов байт-кода. Если у вас установлена версия 2.1, как было подчеркнуто в разделе "Установка", вы имеете дополнительную выгоду, заключающуюся в наличии подключаемого модуля, спроектированного специально для ProGuard. Установить ProGuard так же просто, как и разархивировать proguard.jar и сохранить файл в каталоге bin WTK. Например, если WTK установлен в C:\WTK21, скопируйте файл proguard.jar в C:\WTK21\bin. См. рисунок 10. Рисунок 10. Установка ProGuard
Выполнение ProGuard: Шаг 1Я рассмотрю действия по выполнению ProGuard из WTK. Начнем с запуска WTK и открытия мидлета EncryptText. Запустите процесс засекречивания, выбрав меню Project -> Package -> Create Obfuscated Package. См. рисунок 11. Рисунок 11. Запуск ProGuard Выполнение ProGuard: Шаг 2Шаги для пакетирования мидлета включают в себя перекомпилирование всех исходных Java-файлов, выполнение предварительной проверки class-файлов и, наконец, засекречивание. На рисунке 12 показан снимок экрана WTK, отображающий выполнение процесса засекречивания. Рисунок 12. Засекречивание Выполнение ProGuard: Шаг 3После завершения засекречивания вы должны найти JAR-файл, содержащий засекреченные классы. WTK сохраняет все JAR-файлы мидлетов в каталоге bin проекта. Например, для созданного мной в предыдущем разделе мидлета вы найдете JAR в каталоге C:\WTK21\apps\EncryptText\bin. См. рисунок 13. Рисунок 13. Результаты ProGuard Результат засекречиванияЧтобы иметь представление о том, на что похожи результаты работы обфускатора, давайте рассмотрим один метод в мидлете до и после засекречивания. Метод
Ниже вы можете увидеть, как выглядит засекреченный код:
Очевидно, что его намного труднее прочитать. Обратите внимание на короткие имена переменных и методов. Это один из методов, которые использует обфускатор для уменьшения размера приложения. Как вы помните, обфускатор также удаляет неиспользуемые классы, методы и поля, что обычно является самым существенным методом удаления большого количества кода из мидлета.
Резюме по разделуВ этом разделе был представлен обзор засекречивания, в том числе такие темы: почему засекречивание важно, как работает процесс, и как установить и запустить ProGuard из WTK. Давайте закончим сравнением размера мидлетов до засекречивания и после. Объединяем все вместеОбзорТеперь вы имеете достаточно информации для шифрования и дешифрования данных в приложениях, а также для засекречивания мидлетов. В данном разделе я подробно рассмотрю, что было сделано для экономии байтов в JAR-файлах с засекречиванием и без него. Я начну с рассмотрения мидлета без засекречивания. Пакетирование мидлетаКогда бы я ни выбрал пункт меню Build в WTK, исходный Java-код компилируется и проверяется. Однако по умолчанию WTK не пакетирует мидлет в JAR-файл. Для того чтобы увидеть размер мидлета, включающего весь добавленный код из дополнительных библиотек, я должен указать WTK спакетировать весь код. Из меню Project выберите Package / Create Package. См. рисунок 14. Рисунок 14. Пакетирование мидлета
Размер спакетированного мидлетаДля поиска созданного WTK JAR-файла перейдите в каталог bin проекта EncryptText, например, C:\WTK21\apps\EncryptTest\lib. На рисунке 15 показан размер файла - 547 KB. Излишне говорить, что один этот факт делает мидлет бесполезным для многих мобильных устройств. Рисунок 15. Размер спакетированного мидлета
Засекречивание мидлетаТеперь я заново создам JAR-файл, на этот раз запрашивая ProGuard засекретить содержимое. Из меню Project выберите Package / Create Obfuscated Package. См. рисунок 16. Рисунок 16. Засекречивание мидлета
Размер засекреченного мидлетаСнова найдите каталог bin для того чтобы увидеть размер JAR-файла. Вы заметите значительную разницу после удаления обфускатором всех ненужных классов, методов и полей. На рисунке 17 видно, что было сэкономлено более 500 KB! Рисунок 17. Размер засекреченного мидлета
Ранее говорилось, что WTK 2.x предварительно настроен на работу с ProGuard. Как вы видели в данном руководстве, процесс установки минимален. Однако, выполнив несколько дополнительных действий, вы можете сэкономить еще несколько байтов. Это можно сделать путем даже незначительного изменения конфигурации, запрашивая, чтобы WTK вызывал ProGuard непосредственно во время процесса пакетирования. Отличие в том, как вызывается ProGuard. При существующей конфигурации WTK, когда вы запрашиваете пакетирование/засекречивание с ProGuard, конфигурационный файл записывается на диск, в то время как отдельная виртуальная машина читает файл и выполняет ProGuard на основе содержимого файла. При подходе, который вы здесь увидите, WTK будет вызывать ProGuard напрямую, пропуская необходимость чтения и обработки конфигурационного файла.
Сжатие еще на несколько байт, шаг 1Во-первых, вы должны найти конфигурационный файл ktools.properties. В Windows он находится в каталоге C:\WTK21\wtklib\Windows. На рисунке 18 показано его месторасположение. Рисунок 18. Конфигурационный файл
Сжатие еще на несколько байт, шаг 2Для запроса прямого вызова ProGuard в WTK вы должны изменить в конфигурационном файле строки, сообщающие WTK предпочтительный класс и classpath для ProGuard. Выполните изменения в конфигурационном файле, показанные ниже: Конфигурация по умолчанию
Обновленная конфигурация
Здесь я закомментировал оригинальную конфигурацию и указал класс и classpath расположения JAR-файла ProGuard. Это простое изменение приводит к более эффективному засекречиванию. Важное замечание: Для того чтобы эти изменения вступили в силу, вы должны перезапустить WTK.
Сжатие еще на несколько байт, шаг 3После перезапуска WTK создайте засекреченный пакет так, как я делал ранее. Теперь найдите каталог bin, куда WTK записывает засекреченный JAR-файл. Если вы сравните размер нового JAR-файла с JAR-файлом из предыдущего раздела, то увидите разницу примерно в 3 K. На рисунках 19 и 20 показаны JAR-файлы для оригинального мидлета и для новой конфигурации соответственно. Рисунок 19. Оригинальный засекреченный JAR-файл Используя WTK, вызывающий ProGuard напрямую, вы можете сэкономить еще несколько байт. Рисунок 20. Новый засекреченный JAR-файл Хотя 3 K могут показаться не очень значительным достижением, в мире мобильных приложений эта разница может повлиять на то, загрузится ваш мидлет в устройство или нет.
Резюме по разделуКроме того, что мидлеты становятся более трудными для обратного анализа, засекречивание может иметь значительное влияние на размер вашего приложения. В данном разделе вы увидели, сколько сохраняется пространства после удаления неиспользуемых классов, методов и полей. Для короткого мидлета эта экономия составила более 500 K. РезюмеВ данном руководстве был представлен обзор защиты мобильных приложений. Оно началось с короткого обсуждения шифрования, включая шифры, ключи и алгоритмы. Также был рассмотрен процесс установки API шифрования Bouncy Castle. Предметом рассмотрения следующего раздела была разработка мидлета для демонстрации использования Bouncy Castle API для шифрования и дешифрования простых текстовых строк. После этого вы узнали о засекречивании class-файлов. Специальное внимание было уделено ProGuard, в том числе, интеграции этого инструментального средства с открытым исходным кодом в WTK. В последнем разделе руководства было проведено сравнение размеров JAR-файлов до засекречивания class-файлов и после. Хотя вы только поверхностно познакомились с созданием защищенных мобильных приложений, это руководство послужит отправной точкой в теме шифрования данных. В вашем распоряжении также имеется новый инструмент (обфускатор class-файлов) предназначенный для того, чтобы сделать обратный анализ вашего приложения более трудным. Не забудьте о способности обфускатора удалять неиспользуемые классы, методы и поля, что может привести к созданию значительно меньших JAR-файлов.
|
|