<< Предыдущая

стр. 20
(из 39 стр.)

ОГЛАВЛЕНИЕ

Следующая >>

i на порт принтера (LPT), последовательный порт (СОМ), USB-порт и
1, подключаемые к специальной плате, вставляемой внутрь компьютера.
ю при сравнении ключей анализировать удобство и функциональность
:твующего программного обеспечения. Например, для некоторых се-
в аппаратных ключей разработаны автоматические протекторы, позво-
ие защитить программу "за один клик", а для некоторых такие протек-
отсутствуют.
шленный интерес представляет список языков программирования, для
ых разработчик ключей предоставил библиотеки и примеры. Поддерж-
ыков (доступ к API ключа из определенной среды) нужна для того,
программист смог более эффективно использовать ключ для защиты
эатываемой программы.
i также список аппаратных платформ и операционных систем, для ко-
поддерживается интерфейс с ключом.
"орых может заинтересовать применимость ключа для сетевого лицен-
ания программного обеспечения.
134 Часть III. Как не надо защищать программы

Однако все сказанное о ключах относится скорее к маркетингу, чем к защи-
те информации. Для защиты не важно, какого цвета корпус у ключа и на
каком языке можно читать документацию. А по-настоящему важно только
то, что в ключе является секретным и неповторимым и способно ли это
"нечто" обеспечить необходимый уровень защиты.
Поэтому в дальнейшем ключи рассматриваются исключительно как аппа-
ратные устройства, работающие в определенных условиях и имеющие неко-
торую функциональность. Полезными признаются только те функции, ко-
торые невозможно реализовать чисто программными средствами и для
которых не существует эффективной атаки.
Будем исходить из предположения, что у противника есть физический дос-
туп к ключу, а основная задача заключается в том, чтобы за разумное время
получить копию программы, функционирующую в отсутствие ключа точно
так же, как при его наличии.
Рассматривать атаки на систему, в которой не хватает некоторых узлов, не-
обходимых для работы, особого смысла нет — если зашифровать программу
и не сообщить противнику ключ шифрования, легко получить высокую
стойкость и без применения аппаратных ключей. Только это уже нельзя на-
зывать защитой от копирования.


12.2. Модификация кода и эмуляция
Для того чтобы заставить программу работать так, как она работала бы
с ключом, можно или внести исправления в программу, или эмулировать
наличие ключа. Модификация программы, как правило, возможна лишь
в тех случаях, когда ответы, полученные от ключа, просто проверяются, но
не являются математически необходимыми для обеспечения работоспособ-
ности программы. Но это значит, что ключ, по большому счету, не требует-
ся для достижения полной функциональности. Такое случается, когда про-
грамма не использует всех возможностей ключа или когда возможности
ключа очень ограничены.
При эмуляции никакого воздействия на программу не происходит, т. е., на-
пример, не нарушается контрольная сумма исполняемых модулей. И пол-
ный эмулятор, если его удается построить, просто повторяет все поведение
реального ключа.
Не вдаваясь очень глубоко в технические подробности, будем исходить из
предположения, что у противника есть следующие возможности:
• перехватывать все обращения к ключу;
• протоколировать и анализировать эти обращения;
Глава 12. Аппаратные ключи защиты 135

О посылать запросы к ключу;
• получать ответы от ключа;
• протоколировать и анализировать эти ответы;
• посылать ответы от имени ключа.
Такие широкие возможности противника можно объяснить тем, что в его
распоряжении есть вся та информация, какая есть и у программиста, защи-
щающего программу с помощью аппаратного ключа. То есть противник
имеет доступ ко всем открытым интерфейсам, документации, драйверам и
может их анализировать на практике с привлечением любых средств. Следо-
вательно, можно предположить, что противник со временем научится пол-
ностью контролировать протокол, по которому происходит обмен информа-
цией между прикладной программой и ключом. Контроль может
осуществляться на любом уровне, но чаще всего запросы перехватываются
при передаче данных между программой и драйвером ключа.
Однако стоит учитывать, что возможность эмуляции еще не означает, что
противник способен вычислять правильные ответы на любые запросы, ко-
торые посылает ключу программа.


12.3. Ключи с памятью
Это, наверное, самый простой тип ключей. Ключи с памятью имеют опре-
деленное число ячеек, из которых разрешено считывание. В некоторые из
этих ячеек также может производиться запись. Обычно в ячейках, недоступ-
ных для записи, хранится уникальный идентификатор ключа.
Когда-то давно существовали ключи, в которых перезаписываемой памяти
не было вообще, а программисту для считывания был доступен только иден-
тификатор ключа. Но очевидно, что на ключах с такой функциональностью
построить серьезную защиту просто невозможно.
Правда, и ключи с памятью не способны противостоять эмуляции. Доста-
точно один раз прочитать всю память и сохранить ее в эмуляторе. После
этого правильно эмулировать ответы на все запросы к ключу не составит
большого труда.
Таким образом, аппаратные ключи с памятью в заданных условиях не спо-
собны дать никаких преимуществ по сравнению с чисто программными
системами.

12.4. Ключи с неизвестным алгоритмом
Многие современные аппаратные ключи содержат секретную функцию пре-
образования данных, на которой и основывается секретность ключа. Иногда
136 Часть III. Как не надо защищать программы

программисту предоставляется возможность выбрать константы, являющие-
ся параметрами преобразования, но сам алгоритм остается неизвестным.
Проверка наличия ключа должна выполняться следующим образом. При
разработке защиты программист делает несколько запросов к алгоритму и
запоминает полученные ответы. Эти ответы в какой-то форме кодируются
в программе. Во время выполнения программа повторяет те же запросы и
сравнивает полученные ответы с сохраненными значениями. Если обнару-
живается несовпадение, значит, программа получает ответ не от оригиналь-
ного ключа.
Эта схема имеет один существенный недостаток. Так как защищенная програм-
ма имеет конечный размер, то количество правильных ответов, которые она
может хранить, также является конечным. А это значит, что существует воз-
можность построения табличного эмулятора, который будет знать правильные
ответы на все запросы, результат которых может проверить программа.
В рекомендациях по защите программ с помощью аппаратных ключей да-
ются советы, как сделать фиктивные запросы со случайными данными так,
чтобы затруднить построение эмулятора. Однако если программа при запус-
ке делает 100 запросов, результат которых может быть проверен, и 100 слу-
чайных запросов, результат которых не проверяется, то, запустив программу
10 раз, очень легко выделить действительные запросы, повторившиеся
10 раз, и отсечь все фиктивные, встретившиеся по 1 2 раза.

Конечно, не стоит всегда проверять наличие ключа выполнением одной и
той же серии запросов с проверкой. Лучше выполнять проверки в разных
частях программы и в разное время. Это может значительно усложнить сбор
статистики для отсечения фиктивных запросов.
Но не стоит забывать, что противник может проанализировать программу и
попытаться в дизассемблере найти все обращения к ключу. Это поможет
ему выяснить, ответы на какие из запросов проверяются, и построить ком-
пактную таблицу для эмуляции.
Так что ключи с неизвестным алгоритмом могут затруднить, но не могут
предотвратить построение эмулятора для конкретной версии конкретной
программы. Зато при переходе к новой версии, если перечень проверяемых
программой ответов на запросы будет изменен, противнику придется заново
выполнять сбор статистики или анализ программы.


12.5. Атрибуты алгоритмов
В некоторых ключах алгоритму могут сопутствовать дополнительные атри-
буты. Так, например, в ключах Sentinel SuperPro алгоритм может быть за-
щищен паролем и начинает работать только после того, как будет выполне-
Глава 12. Аппаратные ключи защиты 137

на активация, в ходе которой правильный пароль должен быть передан
ключу.
Активация позволяет разработчику предусмотреть возможность изменения
функциональности ключа на стороне пользователя. То есть программа мо-
жет иметь несколько версий (например базовую, расширенную и профес-
сиональную), и в ключе изначально активированы только те алгоритмы, ко-
торые необходимы для функционирования базовой версии. Если же
пользователь решит перейти к более полной версии, разработчик пришлет
ему инструкции по активации алгоритмов, соответствующих расширенной
или профессиональной версии.
Однако все достоинства алгоритмов, активируемых по паролю, опираются на
секретность пароля, а не на свойства аппаратного ключа. Следовательно, ана-
логичная защита может быть реализована чисто программными средствами.
Другой тип атрибутов алгоритмов, поддерживаемых ключами Sentinel Super-
Pro, — это счетчики. С активным алгоритмом может быть связан счетчик,
изначально имеющий ненулевое значение. Программа при каждом запуске
(или выполнении определенной операции, например при экспорте данных)
вызывает специальную функцию API-ключа, уменьшающую значение счет-
чика на единицу. Как только счетчик принимает нулевое значение, алго-
ритм деактивируется и перестает работать.
Однако данная схема не способна помешать применению эмулятора. Про-
тивник может перехватывать и предотвращать все попытки уменьшения
значения счетчика. Следовательно, алгоритм никогда не будет деактивиро-
ван, и в распоряжении противника будет неограниченное время для сбора
данных, необходимых для табличной эмуляции.
Противостоять эмуляции может счетчик, значение которого уменьшается
при каждом обращении к алгоритму. Но в этом случае возникает опасность,
что из-за сбоев в работе программы или операционной системы иногда зна-
чение счетчика будет уменьшаться без совершения программой полезных
Действий. Причина проблемы в том, что обращение к алгоритму должно
производиться до того, как программа совершит полезную работу, а счетчик
Должен уменьшаться только в том случае, если работа выполнена успешно.
Но автоматическое уменьшение счетчика при обращении к алгоритму такую
Функциональность не обеспечивает — количество оставшихся попыток
Уменьшается независимо от успеха выполненной операции.


12.6. Ключи с таймером
Некоторые производители аппаратных ключей предлагают модели, имею-
щие встроенный таймер. Но для того чтобы таймер мог работать в то время,
138 Часть III. Как не надо защищать программы

когда ключ не подключен к компьютеру, необходим встроенный источник
питания. Среднее время жизни батареи, питающей таймер, составляет 4 го-
да, и после ее разрядки ключ перестанет правильно функционировать. Воз-
можно, именно из-за сравнительно короткого времени жизни ключи с тай-
мером применяются довольно редко.
Но как таймер может помочь усилить защищенность?
Ключи HASP Time предоставляют возможность узнавать текущее время, ус-
тановленное на встроенных в ключ часах. И защищенная программа может
использовать ключ для того, чтобы отследить окончание тестового периода.
Но очевидно, что эмулятор позволяет возвращать любые показания таймера,
т. е. аппаратная часть никак не повышает стойкость защиты.
Хорошей комбинацией является алгоритм, связанный с таймером. Если ал-
горитм может быть деактивирован в определенный день и час, очень легко
будет реализовывать демонстрационные версии программ, ограниченные по
времени.
Но, к сожалению, ни один из двух самых популярных в России разработчи-
ков аппаратных ключей не предоставляет такой возможности. Ключи HASP,
производимые компанией Aladdin, не поддерживают активацию и деактива-
цию алгоритмов. А ключи Sentinel SuperPro, разработанные в Rainbow
Technologies, не содержат таймера.


12.7. Ключи с известным алгоритмом
В некоторых ключах программисту, реализующему защиту, предоставляется
возможность выбрать из множества возможных преобразований данных,
реализуемых ключом, одно конкретное преобразование. Причем подразуме-
вается, что программист знает все детали выбранного преобразования и мо-
жет повторить обратное преобразование в чисто программной системе.
Например, аппаратный ключ реализует симметричный алгоритм шифрова-
ния, а программист имеет возможность выбирать используемый ключ шиф-
рования. Разумеется, ни у кого не должно быть возможности прочитать зна-
чение ключашифрования из аппаратного ключа.
В такой схеме программа может передавать данные на вход аппаратного
ключа и получать в ответ результат шифрования на выбранном ключе.
Но тут возникает дилемма. Если в программе отсутствует ключ шифрова-
ния, то возвращаемые данные можно проверять только табличным спосо-
бом, а значит, в ограниченном объеме. Фактически имеем аппаратный ключ
с неизвестным программе алгоритмом. Если же ключ шифрования известен
программе, то можно проверить правильность обработки любого объема
данных, но при этом существует возможность извлечения ключа шифрова-
Глава 12. Аппаратные ключи защиты 139

ния и построения эмулятора. А если такая возможность существует, против-
ник обязательно попытается ею воспользоваться.
Так что аппаратное выполнение симметричного алгоритма шифрования
с известным ключом не дает ничего нового с точки зрения защиты. Но есть
еще и асимметричные алгоритмы.
Когда ключ реализует асимметричный алгоритм шифрования, программисту
не обязательно знать используемый секретный ключ. Даже можно сказать,
что отсутствие возможности создать программную копию аппаратного
асимметричного шифрующего устройства не сужает, а расширяет область
возможных применений, т. к. сокращается перечень возможных способов
компрометации секретного ключа. В любом случае, для проверки того, что
аппаратный ключ присутствует и правильно выполняет вычисления, доста-
точно знать открытый ключ.
Эта схема не может быть обойдена только эмуляцией, т. к. для построения
полного эмулятора требуется по открытому ключу шифрования вычислить
секретный ключ. А это математически сложная задача, не имеющая эффек-
тивного решения.
Но у противника остается возможность подмены открытого ключа в про-
грамме, и если такая подмена пройдет незамеченной, построить программ-
ный эмулятор не составит труда. Так что асимметричные алгоритмы, реали-
зованные на аппаратном уровне, способны обеспечить некопируемость
защищенной программы, но только в том случае, если удастся предотвра-
тить подмену открытого ключа шифрования.


12.8. Ключи
с программируемым алгоритмом
Очень интересным решением с точки зрения стойкости защиты являются
аппаратные ключи, в которых может быть реализован произвольный алго-
ритм. Сложность алгоритма ограничивается только объемом памяти и сис-
темой команд ключа.
В этом случае для защиты программы важная часть вычислений переносит-
ся в ключ, и у противника не будет возможности запротоколировать пра-
вильные ответы на все запросы или восстановить алгоритм по функции
проверки. Ведь проверка, как таковая, может вообще не выполняться — ре-
зультаты, возвращаемые ключом, являются промежуточными величинами
в вычислении какой-то сложной функции, а подаваемые на вход значения
зависят не от программы, а от обрабатываемых данных.
Главное — это реализовать в ключе такую функцию, чтобы противник не смог
по контексту догадаться, какие именно операции производятся в ключе.
140 Часть III. Как не надо защищать программы


<< Предыдущая

стр. 20
(из 39 стр.)

ОГЛАВЛЕНИЕ

Следующая >>