Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практическая криптография алгоритмы и их программирование

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
Глава 7. Прикладные задачи шифрования 221
Листинг 7.7
В таком случае данные зашифрованного файла по этому же смещению могут выглядеть так же, как и в листинге 7.8 (авторы берут на себя смелость немного свободно обращаться с шифротекстом, однако, как будет показано, это не меняет ситуации в целом):
Листинг 7.8
Если теперь данные из зашифрованного файла сложим по модулю два (ведь по правилу Керкхоффа нам известен способ сложения гаммы с открытым текстом) с данными типового договора, то получим не что иное, как несколько байтов гаммы (см. листинг 7.9). Точно так же мы поступали с текстом «Приветствую, мой нена­глядный сосед!», рассматривая способ подделывания подобных сообщений.
Листинг 7.9
Байты из типового договора по смещению 500h:
C420CE20C320CE20C220CE20D0202020 ДОГОВОР .
Складываем с байтами шифротекста договора по тому же смещению:
F2 A9 BC 9B 37 FD 49 C0 1E 89 20 EC 3A B9 F1 2E ªé+Û7¤I+-É ü:|¸.
И получаем байты гаммы:
36 89 72 BB F4 DD 87 E0 DC A9 EE CC EA 99 D1 0E ªé+Û7¤I+-É ü:|¸.
Теперь допустим, мы каким-либо образом узнали, что сделка была оформлена на общую сумму $15000. Следовательно, эта сумма была проставлена в докумен­те, зашифрованный вариант которого мы имеем.
222 Глава 7. Прикладные задачи шифрования
Посмотрим на документ — поле для ввода суммы сделки находится по смеще­нию 562h (1378) в файле. Можно предположить, и это почти наверняка окажется так, что и в зашифрованном файле по тому же смещению находится строка «$15000».
42
Если злоумышленник
задастся целью подделать сумму сделки, он может в этом преуспеть, сделав всего несколько простых вычислительных действий при помощи средств модулярной арифметики.
Итак, следуя данному немного выше примеру и сделав предположение, что сумма равна ни больше ни меньше $15000, сложим по модулю два байты строки в зашифрованном тексте, начиная со смещения 562h (именно там находится сумма договора), с байтами строки «$15000» — предполагаемой нами суммой. Резуль­тат отражен в листинге 7.10.
Листинг 7.10
7E DA 16 35 8F 86 6C 52 2D 8F F2 FB 2A C7 E9 85 ~+_5ÏÆlR-Ϫ_*|ùÅ
cкладываем с байтами строки "$15000":
24 31 35 30 30 30 $15000
И получаем байты гаммы:
32 04 BA B6 5C 62 2_||\b
Получив таким простым образом уже не просто несколько байтов гаммы, а участок гаммы, где находится интересующая нас информация, мы можем зашиф­ровать все, что нам заблагорассудится. В нашем случае это любая сумма догово­ра. А затем мы можем поместить результат по выбранному смещению обратно в зашифрованный файл и выслать его действительному получателю.
Уменьшим слегка сумму контракта, сложив байты шифротекста с байтами строки «$00000» (см. листинг 7.12):
Листинг 7.11
cкладываем байты гаммы:
32 04 BA B6 5C 62 2_||\b
с байтами строки "$00000":
24 30 30 30 30 30 $00000
и снова получаем байты шифротекста:
16 34 8A 86 6C 52 .4ÊÆlR
В результате этих действий получаем почти тот же зашифрованный текст, но теперь в контракте стоит совершенно другая сумма (см. листинг 7.12, рамочкой обведены изменившиеся байты).
42
Авторы ни в коем случае не хотели бы ставить себя и тем более читателя на место зло
умышленника, но — «увы и ах!» — криптоаналитику всегда приходится это делать.
-
Глава 7. Прикладные задачи шифрования 223
Листинг 7.12
Таким образом, для выбранного специалистами фирмы «Рога и Копыта» спо­соба шифрования (то есть однократного шифрования равновероятной гаммой) су­ществуют вполне приемлемые условия, при которых может быть использован по крайней мере один способ подделки сообщений. А это уже весьма ощутимый ре­зультат, который может оказаться «последней ошибкой».
Аналогичным и еще более простым с точки зрения криптоанализа примером является шифрование методом однократного гаммирования электронных почто­вых сообщений.
Сообщения электронной почты в сети Интернет передаются (как и многие другие данные простых сетевых протоколов прикладного уровня) в текстовом виде, приемлемом для анализа невооруженным взглядом. В листинге 7.13 пред­ставлен пример почтового сообщения в том виде, в котором оно путешествует в сети от компьютера к компьютеру. А листинг 7.14 содержит то же самое сообще­ние, но так, как его видит рядовой пользователь.
Листинг 7.13
From POPmail Tue Nov 17 18:45:15 1998
(with Netcom Interactive pop3d (v1.21.1 1998/05/07) Wed Nov 18 02:39:15 1998) X-From_: seg@crow.sec.gov Tue Nov 17 20:36:28 1998 Received: from crow.sec.gov (crow.sec.gov [204.192.28.11]) by multi33.netcomi.com (8.8.5/8.7.4) with ESMTP id UAA32707 for <fc@all.net>; Tue, 17 Nov 1998 20:36:28 -0600 Received: (from seg@localhost) by crow.sec.gov id VAA01882 for fc@all.net; Tue, 17 Nov 1998 21:37:15 -0500 From: Joe Segreti <seg@crow.sec.gov> Message-Id: <199811180237.VAA01882@crow.sec.gov> Subject: Ответ на пpедложение To: fc@all.net Date: Tue, 17 Nov 1998 21:37:14 -0500 (EST) X-Mailer: ELM [version 2.4 PL25 PGP7] MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit
Добpого вpемени суток!
Уважаемые коллеги, пpедлагаем вам следующую фоpму сотpудничества. ...
224 Глава 7. Прикладные задачи шифрования
Листинг 7.14
Date: Tue, 17 Nov 1998 21:37:14 -0500 (EST) From: Joe Segreti <seg@crow.sec.gov> To: fc@all.net Subject: Ответ на пpедложение
Добpого вpемени суток!
Уважаемые коллеги, пpедлагаем вам следующую фоpму сотpудничества. ...
И в том и в другом случае в сообщении остается много служебных слов, кото­рые используются почтовым программным обеспечением для доставки сообщения адресату. Например, ключевое слово Date: и следующая за ним дата отсылки пи­сьма является обязательным атрибутом любого письма. И точно так же, как под­вергся анализу текстовый файл формата MSWord, мы можем подвергнуть приста­льному изучению это электронное сообщение, подставив, к примеру, другую дату
43
отсылки письма или изменив приветствие и подпись
.
Собственно говоря, все приведенные примеры и недостатки и есть ответ на вопрос, почему почти никто не пользуется методом однократного гаммирова­ния — все зависит от того, как именно это делается и какими ресурсами обладает пользователь шифросистемы.
Криптографическая защита исходных текстов
Время реакции на весьма динамично развивающуюся среду веб-технологий определяет эффективность работы любого Интернет-сайта. Современные техно­логии создания веб-контента в режиме реального времени дали профессионально­му веб-мастеру мощнейшие инструменты для управления потоками информации в Интернет. В условиях постоянного роста производительности использование язы­ков сценариев или, как их еще называют, scripting languages или scripts стало од­ним из опорных решений фундаментального подхода организации инфраструкту­ры Интернет-сайтов. Мощные, легко осваиваемые специализированные языки программирования, ориентированные на разработчиков веб-сайтов, получили ши­рочайшее распространение. Языки сценариев изначально были ориентированы на быстрое и эффективное решение иных задач, нежели языки программирования системного уровня, поскольку они создавались как логически связующие компо­ненты к уже готовым программным решениям. Преимущества такого подхода пе­ред традиционным статическим наполнением веб-порталов видны невооружен­ным взглядом. Это и гибкость построения гипертекстовых переходов, и возмож­ность создания отчетов по записям в базах данных в реальном времени, и генерация комплексных веб-документов из существующих элементарных компо­нентов.
43
Чтобы узнать приветствие и подпись другого человека, иногда бывает достаточно просто написать ему письмо так, как будто бы вы ошиблись адресом. Ответ от него с сообщением об этом будет наверняка содержать всю необходимую информацию.
Глава 7. Прикладные задачи шифрования 225
Точно так же, как и несколько лет назад в малых интегрированных сетях, в программировании контента публичных серверов существует два подхода. А именно создание интерпретируемых сценариев и компиляция байт-кода. Пер­вый подход не выходит за рамки CGI-программирования, согласно которому для разработки гипертекстовой страницы нужен только обычный текстовый редактор, а сам гипертекстовый документ должен легко читаться человеком. Второй подход повышает эффективность исполнения программы, а также защищенность кода от доступа и несанкционированных изменений.
Реализации интерпретаторов таких языков сценариев, как Perl и Phyton, в це­лях повышения эффективности перед исполнением сценария проводят предвари­тельную перекомпиляцию в специальный мобильный байт-код. Для обозначения байт-кода существует даже собственное название — пи-код (p-code). Такое назва­ние байт-коду было дано одним из создателей «псевдомашины» (p-system) — опе­рационной системы для микроконтроллеров (и, например, машин CP/M), кото­рая разрабатывалась в 1977 году и работала как эмулирующий интерпретатор языка UCSD Pascal. Автор UCSD Паскаля — Урс Арманн (Urs Armann) вместе с профессором Кеннетом Боулсом (Kenneth Bowles) и дали название коду, в кото­рый компилировались исходные тексты.
Такой код, будучи сформирован в результате трансляции исходного текста сценария, записывается в память или файл и лишь потом обрабатывается интерп­ретатором. Для языка Python файлы с байт-кодом (они имеют специальное расши­рение *.pyc) в дальнейшем можно спокойно переносить с платформы на платфор­му и исполнять с равными правами как, к примеру, на Sun, так и на Intel PC/win32 — мобильность пи-кода это позволяет.
В конце 90-х годов прошлого столетия CGI-программирование — а это авто­матизация, гостевые книги, форумы, опросы, списки рассылки, интерфейсы к ба­зам данных и многое другое — стало наиболее популярным и эффективным спо­собом организации интерактивного взаимодействия с пользователями. Как и в любой другой области программирования, стали возникать свои вопросы и проб­лемы.
Одними из самых интересных и неоднозначных вопросов были и остаются во­просы о защите программных кодов и исходных текстов от несанкционированной модификации и копирования. Актуальность стоящих проблем защиты програм­много обеспечения очевидна хотя бы потому, что все сценарные языки, такие, как Perl, Phyton, JavaScript и всевозможные производные с постфиксом *script (то есть VBScript, PerlScript и т. д.), являются интерпретируемыми, и ни о каких би­нарных кодах и скрытом исходном тексте не может идти и речи.
В этом случае исследованию алгоритма работы сценария и использованию его без разрешения авторов не создано никаких препятствий. Программисты, со­здающие средства веб-автоматизации, пытаются решить эту проблему всевозмож­ными способами, прибегая порой к изощренным методикам сокрытия исходных текстов и защиты их от модификации. Собственно говоря, защита от модифика­ции хороша также и как защита, что называется, «от дурака», что немаловажно при продаже программного обеспечения не в комплексе, а как отдельной едини­цы, когда приобретающий программное обеспечение пользователь получает пол
-
226 Глава 7. Прикладные задачи шифрования
ный доступ не только к конфигурационным файлам, но и к пакету самих сценари­ев. И при отсутствии у него должной квалификации внесенные в сценарий изме­нения могут существенно повлиять на отказоустойчивость и работоспособность всего комплекса. Кроме того, как показывает практика обеспечения информаци­онной безопасности в открытых системах, программное обеспечение веб-серверов зачастую столь несовершенно, что при достаточной сноровке злоумышленник вполне способен получить исходный текст сценариев веб-сервера (классическим примером может послужить инцидент с веб-сервером WebTrends, который позво­лял получить исходный текст сценариев, просто добавив пробел к его имени в строке запроса. Òàê, запрос ïî адресу «http://somewhere.in.the.inter-
net.com/cgi-bin/script.pl» запускал script.pl на исполнение, а запрос к «http://somewhere.in.the.internet.com/cgi-bin/script.pl%20» выдавал исход-
ный текст сценария любому неавторизованному пользователю.
На сегодняшний день существует несколько способов защитить исходные тексты программных модулей для интерпретаторов от модификации и даже со­всем скрыть их от глаз пользователя. Рассмотрим их на примере одного из самых популярных в сети Интернет (то есть по всему миру) языка сценариев Perl.
Одним из вариантов сокрытия исходных текстов является возможность «ком­пилирования» исходных текстов в исполняемый бинарный код (формат PE-exe для win32 платформ и ELF для Linux/BSD). Для этого исходный текст может быть скрыт внутри исполнимого файла (например, сжат с помощью алгоритма криптографического сжатия). Сам исполнимый файл в этом случае представляет собой пригодный для исполнения файл, содержащий полную реализацию функ­ций интерпретатора программного языка, на котором написан исходный текст за­щищаемого скрипта. После начала исполнения исполнимый файл разархивирует исходный текст скрипта и исполняет его с помощью встроенного интерпретатора.
В случае с Perl для этого используется технология «Perl Embedded in C», раз­работанная Ларри Уоллом, инструментарий для которой распространяется вмес­те с интерпретаторами языка сценариев Perl бесплатно.
В начале апреля 2002 года среди писем, распространяемых в популярной рас­сылке BugTraq, посвященной информационной безопасности и, в частности, вы­явлению фактов уязвимости программного обеспечения, можно было встретить письма о безопасности предлагаемого разработчиками IndigoStar Software рас­пространения исходных текстов сценариев в виде бинарных файлов. Данное про­граммное обеспечение (утилита Perl2Exe, распространяемая в виде shareware sof­tware, то есть за деньги) реализует описанную выше функциональность.
Несмотря на то что авторы утилиты Perl2Exe не предоставляют ее исходных текстов, оказалось возможным, исследовав ее программный код, найти инженер­ный пароль и способ зашифрования исходных текстов. Более того, это оказалось возможно делать в совершенно автоматическом режиме, без участия челове­ка-оператора. Говорить о криптографической стойкости примененного метода бессмысленно, поскольку ключ к шифру находится в исполнимом файле рядом с самим шифром.
Таким образом, чтобы извлечь исходный текст из бинарного файла, достаточ­но запустить на исполнение специальную утилиту, совершающую обратное пре
-
Глава 7. Прикладные задачи шифрования 227
образование Exe2Perl. Автором одной из таких утилит, с легкостью позволяющей «доставать» исходные тексты, является Четан Ганатра (Chetan Ganatra, ganat­ras@infotech.icici.com).
Следующим способом сокрытия исходных текстов и их защиты от несанкцио­нированной модификации можно указать встроенные средства языка Perl. Это так называемые фильтры исходных текстов или source filters.
Необходимость создания механизма подобных фильтров была продиктована именно соображениями защиты исходных текстов сценариев. Защищенный сце­нарий может выглядеть следующим образом:
#!/bin/perl use DecipherModule; @*x$]'0uN&k^Zx02jZ^X{.?s!(f;9Q/^A^@~~8H]|,%@^P:q-= jkhsdk$*#@&((#$Y%@ #EDUF(HFU#@H(@#(F(@#CDLnclser#@ sd0U3R0FR32 239RUW0EFR&y^3843#q*%&^#$##@ ERFSDHFF= #&^*&$e(*#qyr(#@yrHFhwp4y$@#83yhFwhEhfishfjlq247@$ ...
Фильтры исходных текстов в частном случае позволяют зашифровать и/или заархивировать часть основного тела сценария так, что сначала будет загружен специальный модуль, который будет расшифровывать остальную часть сценария построчно.
Конечно, преимущества такого подхода, возможно, не очевидны на первый взгляд. Для этого необходимо чуть более детально разобраться в достаточно уни­версальном механизме фильтров исходных текстов. На первый взгляд этот весьма специфичный инструмент несет в себе возможности и разработки нескольких по­следних лет в смежных областях программирования и защиты программного обеспечения. Многие технологии защиты программного обеспечения от несанк­ционированного копирования и использования могут быть с легкостью перенесе­ны на «почву» фильтров исходных текстов и использованы для веб-сценариев. И здесь точно так же, как и на платформах с win32, существуют те же проблемы и методы обхода защитных барьеров.
Самым уязвимым в смысле защиты от исследования сценария является мо­дуль расшифрования основного тела исходного текста. Он может быть написан на самом языке Perl, но тогда достаточно будет исследовать его, что является в об­щем-то тривиальной задачей, поскольку он не может быть зашифрован. Кроме этого, если алгоритм зашифрования достаточно сложен, расшифровка всего ис­ходного текста может занять долгое время, что неизбежно скажется на эффектив­ности функционирования веб-узла, а это нежелательно ни при каких обстоятель­ствах. Очевидно, что в этом случае применять шифрование может быть не очень удачным решением. Однако в качестве расшифровывающего модуля можно испо­льзовать своего рода плагин (plugin), то есть специальную подключаемую библио­теку, написанную на любом другом языке и откомпилированную как разделяемый модуль (shared library).
Используя специальный набор функций Perl API, данный модуль расшифрует исходный текст гораздо быстрее, чем если бы он сам был написан на языке Perl. Кроме того, такой подход позволяет на полную мощность использовать средства
228 Глава 7. Прикладные задачи шифрования
усложнения анализа программного кода, включая такие известные приемы, как применение самомодифицирующегося кода, шифрование/расшифрование «на лету», во время исполнения процедур модуля.
Чтобы не давать голословных утверждений, попробуем реализовать подобное программное обеспечение. В качестве алгоритма шифрования мы можем исполь­зовать один из уже реализованных в предыдущих главах алгоритмов. Попробуем остановиться на алгоритме RC4. Для его использования нам понадобится простая программа, которая будет зашифровывать любые наши данные с помощью RC4 и заданного нами ключа (см. листинг 7.15).
Листинг 7.15
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <time.h> #include "hexdump.h" #include "rc4.h"
#define RC4_KEYSIZE 32
void prepare_pass(uchar *pass) {
srandom(time(NULL)); memset(pass, 0, sizeof(pass)); for(inti=0;i<RC4_KEYSIZE; i++) pass[i] = random()+i*i; for(inti=0;i<sizeof(pass); i++) pass[i] ^= pass[sizeof(pass) - i];
}
void main(int argc, char *argv[]) {
FILE *f, *f_ec; RC4_KEY key; char buf[1024]; uchar pass[RC4_KEYSIZE]; int read;
printf("Scripher RC4-Encoder\n[c] Roman A. Hady, Specvuzautomatika\n\n"); if (argc == 1 || argc > 2) {
printf("Usage: encoder file_to_encode\n\n"); exit(1);
}
prepare_pass(pass); strcpy(buf, argv[1]); strcat(buf, ".pass"); f = fopen(buf, "wb"); if (!f) {
printf("Can't open %s for write\n", buf);
exit(2); } fwrite(pass, sizeof(pass), 1, f); fclose(f);
setup_rc4_key(&key, pass, sizeof(pass));
Глава 7. Прикладные задачи шифрования 229
f = fopen(argv[1], "rb"); if (!f) {
printf("Can't open %s for read\n", argv[1]);
exit(2); }
strcpy(buf, argv[1]); strcat(buf, ".coded"); f_ec = fopen(buf, "wb"); if (!f) {
printf("Can't open %s for read\n", buf);
exit(2); }
do {
read = fread(buf, 1, sizeof(buf), f);
if (read <= 0) break;
hexdump((uchar *) buf, read, 16, NULL);
encode_rc4((uchar *) buf, read, &key);
hexdump((uchar *) buf, read, 16, NULL);
fwrite(buf, 1, read, f_ec); } while (1);
fclose(f); fclose(f_ec); printf("\nOK. Job done.\n");
}
Программа из листинга 7.15 работает с несколькими файлами: на вход ей по­дается имя файла, который необходимо зашифровать. При этом программе пона­добится файл с таким же именем, но с дополнительным расширением *.pass, ко­торый будет содержать сгенерированный программой случайным образом пароль шифрования. Именно этим паролем и будет зашифрован исходный файл данных. Файл данных в нашем случае будет не чем иным, как исходным текстом скрипта, который нужно защитить от модификации и просмотра пользователем.
Для работы с этим зашифрованным файлом нам понадобится специальный механизм обработки зашифрованных данных и их интерпретации с помощью ин­терпретатора языка Perl.
Все это мы можем осуществить с помощью механизма Perl source filters. Для этого мы должны создать специальный программный модуль в системе интерпре­татора языка Perl, который взял бы на себя функции обработки зашифрованного текста. Авторы дали название данной системе Scripher как производное от script è cipher.
Более того, нам необходимо написать этот модуль не на Perl'е, а на другом — компилируемом в бинарный код языке (например, Си), который предоставит до­полнительный уровень защиты, и каким-то образом реализовать его сопряжение с системой интерпретатора.
На самом деле это не очень сложно. Для этого понадобится интерфейсный модуль scripher.pm, написанный на Perl (см. листинг 7.16) и модуль обработки данных, написанный на Си, но оформленный в специальном формате XS.
230 Глава 7. Прикладные задачи шифрования
Листинг 7.16
package scripher;
require DynaLoader; @ISA = qw(DynaLoader); $VERSION = "0.0.1"; bootstrap scripher $VERSION;
1; __END__
А сам модуль, оформленный по форме XS, выглядит следующим образом (см. листинг 7.17). На самом деле это обычный файл исходного текста на языке Си, но содержащий дополнительную информацию для динамической линковки и связи с интерпретатором Perl.
Листинг 7.16
/*
* Filename : scripher.xs * * Author : A.V. Agranovsky & R.A. Hady * Date : 25.04.2001 * Version : 1.0.1 * */
#ifdef __cplusplus extern "C" { #endif
#include "EXTERN.h" #include "perl.h" #include "XSUB.h"
#ifdef __cplusplus } #endif
, размер ключа для RC4 #define RC4_KEYSIZE 32
#define HEADER_SIZE (4+4+4+RC4_KEYSIZE)
, SEGMENT_SIZE must be greater than HEADER_SIZE #define SEGMENT_SIZE (((HEADER_SIZE + 16) / 16) * 16)
, check for correct ID and cipher version stamp #define RIGHT_ID 0xDEADFACE #define RC4_CIPHER 0xC4C4C401
#define uchar unsigned char #define decode_rc4 encode_rc4
, заголовок - первые несколько байтов зашифрованных данных typedef struct SCR_HEAD_t {
long ID;
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]