УДК 004.056.55
СОЗДАНИЕ КОМПЛЕКСНОЙ ЗАЩИТЫ ПРОГРАММНОГО КОДА С
ИСПОЛЬЗОВАНИЕМ ОБФУСКАЦИИ
А.И. Никонов, д.т.н, профессор кафедры ЭСИБ
СамГТУ(Самара, Россия)
А.А. Мышенков, аспирант кафедры ЭСИБ СамГТУ(Самара,
Россия)
Введение
С постоянным ростом вычислительных возможностей и
увеличением скорости работы компьютерных систем требования к защите алгоритмов
и программ становятся все более жесткими. Высокая вычислительная способность
современных систем облегчает действия злоумышленника, который нацелен на
несанкционированное получение данных путем анализа и дешифрования.
Целью данной статьи является исследование возможного
варианта комплексной защиты программного кода и алгоритмов от анализа.
Способствовать многократному увеличению времени,
требуемого для обратного анализа защищаемого алгоритма, в данном случае должен
процесс обфускации в комплексе с шифрованием. В связи с этим следует
производить соответствующее комплексирование алгоритмов шифрования и
обфускации, а это, в свою очередь предполагает проведение обоснованного выбора
алгоритмов шифрования. Такой выбор должен основываться, в частности на
использовании следующих критериев:
·
криптостойкости;
·
быстродействия;
Алгоритм обфускации в комплексе с шифрованием.
Защиту программного кода предлагается осуществлять по
алгоритму, содержащему следующие фрагменты:
·
замена текстовых и
числовых значений зашифрованными и подстановка вызова функции дешифрования
·
преобразование потока
управления;
·
преобразование форматирования;
·
преобразование структур
данных и переименование переменных;
·
внесение функции
дешифрования в алгоритм программы;
·
превентивные
преобразования;
·
шифрование кода или
некоторых участков кода, подстановка вызова функции дешифрования перед
непосредственным исполнением данных участков кода;
·
шифрование ключа
асимметричным алгоритмом шифрования;
Преобразования потока
управления программы изменяют структуру её графа потока управления,
например, такие, как развёртка циклов, выделение фрагментов кода в процедуры,
добавление условных переходов и невыполняемых условных блоков;
преобразования структур данных изменяют структуры данных, с
которыми работает программа; к этой группе относятся, например, преобразование,
изменяющее иерархию наследования классов в программе, или преобразование,
объединяющее скалярные переменные одного типа в массив; преобразования форматирования
изменяют только внешний вид программы; к этой группе относятся преобразования,
удаляющие комментарии, отступы в тексте программы или переименовывающие
идентификаторы; превентивные преобразования, нацеленные против
определённых методов декомпиляции программ или использующие ошибки в
определённых инструментальных средствах декомпиляции[5].
Блок-схема
алгоритма обфускации и шифрования защищаемого программного кода изображена на
рисунке 1.
Если для зашифрования использовался криптостойкий алгоритм шифрования, то при отсутствии правильного ключа k2 получить M' = M невозможно. Криптостойкость - основная характеристика алгоритмов шифрования и указывает прежде всего на степень сложности получения исходного текста из зашифрованного без ключа k2.
Алгоритмы шифрования можно разделить на две категории: симметричного и асимметричного шифрования. Для первых соотношение ключей зашифрования и расшифрования определяется как k1 = k2 = k (т. е. функции E и D используют один и тот же ключ шифрования). При асимметричном шифровании ключ зашифрования k1 вычисляется по ключу k2 таким образом, что обратное преобразование невозможно, например, по формуле k1 = ak2 mod p (a и p - параметры используемого алгоритма).
При
шифровании данных, используемых в программе, например, строк, эти данные
шифруются. Затем зашифрованная строка подставляется в качестве параметра в
вызов процедуры дешифрования. При правильном вызове этой функции, она вернет
верное значение. Для лучшей защиты ключ тоже должен быть зашифрован.
В
асимметричных системах необходимо применять длинные ключи что, резко
увеличивает время шифрования. Кроме того, генерация ключей весьма длительна,
зато распределять ключи можно по незащищенным каналам.
Рисунок 1 Блок-схема процесса обфускации и
шифрования защищаемого программного кода
В
симметричных алгоритмах используют более короткие ключи, т. е. шифрование
происходит быстрее. Для шифрования программного кода наиболее подходят блочные
алгоритмы шифрования, т.к. требуется шифровать достаточно большие объемы
данных. К тому же блочные шифры намного надежнее поточных. Однако в таких
системах сложнее распределять ключи.
Так
как для шифрования и дешифрования кода алгоритма или программы требуется
значительная скорость, участки исполняемого кода программы должны быть
зашифрованы с помощью алгоритма симметричного шифрования. Затем ключ, которым
был зашифрован код, шифруется симметричным алгоритмом. Таким образом, для
защиты программного алгоритма мы будем использовать комплекс из алгоритма
обфускации совместно с двумя алгоритмами шифрования – симметричным и
ассиметричным.
При
выборе симметричного алгоритма для шифрования программного кода будем
основываться на критериях быстродействия и криптостойкости.
Выбор
алгоритмов шифрования.
Все
современные криптосистемы построены по принципу Кирхгоффа, то есть секретность
зашифрованных сообщений определяется секретностью ключа. Это значит, что даже
если сам алгоритм шифрования известен криптоаналитику, тот, тем не менее, не в
состоянии расшифровать сообщение, если не располагает соответствующим ключом.
Шифр считается хорошо спроектированным, если нет способа вскрыть его более
эффективным способом, чем полным перебором по всему ключевому пространству,
т.е. по всем возможным значениям ключа. ГОСТ, вероятно, соответствует этому
принципу – за годы интенсивных исследований не было предложено ни одного
результативного способа его криптоанализа. В плане стойкости он на много
порядков превосходит прежний американский стандарт шифрования, DES.
Ни
одна из рассмотренных автором реализаций DESа для платформы Intel x86 не
достигает даже половины производительности реализации ГОСТа несмотря на вдвое
более короткий цикл. Разработчики ГОСТа учли как положительные, так и
отрицательные стороны DESа, а также более реально оценили текущие и
перспективные возможности криптоанализа. Впрочем, брать DES за основу при
сравнении быстродействия реализаций шифров уже не актуально. У нового стандарта
шифрования США дела с эффективностью обстоят гораздо лучше – при таком же как у
ГОСТа размере ключа в 256 бит AES работает быстрее него примерно на 14% – это
если сравнивать по числу «элементарных операций». Кроме того, ГОСТ практически
не удается распараллелить, а у AES возможностей в этом плане намного больше. На
некоторых архитектурах это преимущество AES может быть меньше, на других –
больше. Так, на процессоре Intel Pentium оно достигает 28%[4].
Для того, чтобы результат расшифрования совпал с исходным сообщением (т. е. чтобы M' = M), необходимо одновременное выполнение двух условий. Во-первых, функция расшифрования D должна соответствовать функции зашифрования E. Во-вторых, ключ расшифрования k2 должен соответствовать ключу зашифрования k1.
Алгоритм ГОСТ
28147-89 считается очень сильным алгоритмом - в настоящее время для его
раскрытия не предложено более эффективных методов, чем упомянутый выше метод
"грубой силы". Его высокая стойкость достигается в первую очередь за
счет большой длины ключа - 256 бит. При использовании секретной синхропосылки
эффективная длина ключа увеличивается до 320 бит, а засекречивание таблицы
замен прибавляет дополнительные биты. Кроме того, криптостойкость зависит от
количества раундов преобразований, которых по ГОСТ 28147-89 должно быть 32
(полный эффект рассеивания входных данных достигается уже после 8 раундов)[1].
В отличие от
алгоритма ГОСТ 28147-89, который долгое время оставался секретным, американский
стандарт шифрования AES, призванный заменить DES, выбирался на открытом
конкурсе, где все заинтересованные организации и частные лица могли изучать и
комментировать алгоритмы-претенденты.
Алгоритм
Rijndael не похож на большинство известных алгоритмов симметричного шифрования,
структура которых носит название "сеть Фейстеля" и аналогична
российскому ГОСТ 28147-89. Особенность сети Фейстеля состоит в том, что входное
значение разбивается на два и более субблоков, часть из которых в каждом раунде
обрабатывается по определенному закону, после чего накладывается на
необрабатываемые субблоки.[2]
Основываясь на высоких показателях двух этих алгоритмов можно сделать вывод, что они подходят для использования в нашем исследуемом алгоритме комплексной обфускации.
Ключ для шифрования (и
соответственно расшифрования) кода должен быть надежно защищен. В идеале, он
должен отличаться для каждого пользователя программы. Однако такой подход
является неприемлемым для продуктов с большим количеством пользователей,
поскольку предполагает, что каждому пользователю будет выдаваться отдельная
копия продукта, зашифрованная ключом этого пользователя.
Исходя из этого ключ тоже должен быть зашифрован. Так как
величина ключа в отличие от размеров исходного кода невелика, скорость
алгоритма шифрования не имеет особого значения. Следовательно, целесообразно
использовать ассиметричный алгоритм шифрования, например, RSA
Разработанный
в 1978 г. тремя авторами (Rivest, Shamir, Adleman), он получил свое название по
первым буквам фамилий разработчиков. Надежность алгоритма основывается на
сложности факторизации больших чисел и вычисления дискретных логарифмов.
Основной параметр алгоритма RSA - модуль системы N, по которому проводятся все
вычисления в системе, а N = P*Q (P и Q - секретные случайные простые большие
числа, обычно одинаковой размерности).
Все участки данного алгоритма
защиты, относящиеся к обфускации, выполняют такое преобразование кода, которое
сохраняет работоспособность программы, в отличие от шифрования. Поэтому
требуется добавлять процедуры дешифрования перед исполнением основного кода
программы. А после выполнения данных участков они должны быть вновь зашифрованы[3].
Рисунок 2 Алгоритм работы программы после
Комплексной обфускации
Разработка способа
комплексирования.
Механизм
комплексирования может вырабатываться с использованием методики, излагаемой
ниже:
1. Анализ прототипа
2. Формулировка предложения
3. Улучшаемая характеристика
4. Технические затраты на улучшение
5. Заключение о целесообразности данного улучшения
Работа
данной методики показана на примере комплексирования способа обфускации путем
добавления условных переходов и способа
обфускации путем шифрования ключей.
1.
Допустим, имеется программа, написанная на скриптовом языке
программирования, которую необходимо защитить. Время, которое потратит
злоумышленник на анализ исходного кода, примем равным t. Значение времени t минимально,
так как для анализа исходного кода скриптовой программы не требует декомпиляции
и дизассемблирования. Таким образом, для защиты программы от обратного анализа
требуется значительное увеличение времени t.
2.
При совмещении методов обфускации и шифрования в данном случае предлагается
следующее:
·
добавление в код программы множества условных переходов, таким образом
запутывающих критический путь программы, добавляя множество ложных путей. Для
этого необходимо разработать некий параметр, с помощью которого должен
исполняться истинный путь программы в режиме нормальной работы, ложные пути
программы в режиме отладки или нарушения целостности кода (программы). Это
необходимо для того чтобы противодействовать так называемым сканерам
критического пути или охвата кода.
·
Передача зашифрованного ключа вглубь программы
·
Дешифрование ключа по мере выполнения программы а не перед ее выполнением
·
Добавление в каждый условный переход процедуры дешифрования ключа с ложным
результатом, кроме одной необходимой при выполнении критического пути программы
3.
Улучшаемая характеристика – криптостойкость
Пусть
∆ti – повышение времени анализа программного кода,
защищенного способом шифрования 1(шифрование ключей), ∆tj – повышение времени анализа программного кода, защищенного способом
обфускации 4.
Предположим,
что максимальное ∆tj является общим временем,
потраченным на анализ каждого пути программы, включая ложные.
При
использовании метода обфускации 4 и метода шифрования 1 повышение времени
обратного анализа будет равно следующему
При
комплексировании этих методов получаем следующее
Отсюда
следует что .
4.
Технические затраты на улучшение – уменьшение производительности
(увеличение размеров исходного кода, времени исполнения обфусцированного кода)
Так
как при правильных условиях выполнение программы пойдет только по критическому
пути, увеличение размеров исходного кода не повлияет
5.
Исходя из вышесказанного, можно сделать вывод, что с использованием
комплексирования данных способов действительно возможно улучшить характеристику
криптостойкости.
Заключение
В данной работе был рассмотрен вариант
комплексирования обфускации и шифрования с возможностью использования методики
выявления соответствующих приемов информационного улучшения. Были выбраны
подходящие алгоритмы шифрования, причем для шифрования участков кода
рассмотрены алгоритмы ГОСТ 28147-89 и AES, а для шифрования ключа
предусмотрено использование алгоритма RSA.
Библиографический список