Абсолютный шифровальщик

ИНСТРУКЦИЯ
пользователя программы
Шифровальщик "ШТОРМ" v 5.0



ВВЕДЕНИЕ


Обычно для шифрования своих файлов пользователи применяют стандартные приёмы: средства паролирования файла в Word-е или Excel-е, либо ввод пароля при архивировании. Преимущества этих методов в том, что средства создания защиты настолько распространены, что нет необходимости постоянно носить с собой программы шифрования, достаточно знать, как воспользоваться нужной функцией и запомнить пароль. Но как показывает практика, именно доступность стандартных средств шифрования приводит к появлению программ "взлома паролей" для этих средств. Так что надёжность защиты при помощи продуктов даже именитых фирм остаётся под вопросом.

Поучителен случай из моей практики, когда я послал ARJ-архив своему другу с туманным намёком на пароль в надежде, что он догадается, а посторонний человек не поймёт о чём идёт речь. Посторонний-то не понял, но и друг не догадался! Но он не растерялся, полез в Интернет и откапал там программу взлома запаролированных ARJ-архивов. С тех пор я уверен лишь в собственных
программах защиты информации.

Почему возможен взлом такой защиты, как в ARJ-архиве? Потому что ПАРОЛЬ хранится где-то ВНУТРИ АРХИВА, и программа в какой-то момент сравнивает введенный пользователем пароль с эталоном и сообщает, что ПАРОЛЬ НЕВЕРЕН. А значит можно найти это место и посмотреть, а с чем же ты сравниваешь, дорогая?

Допустим, что нас по каким-либо причинам не устраивает такое положение вещей, и мы хотим создать собственный шифровальный алгоритм, который при надлежащем обслуживании нами, дал 100%-ную гарантию защиты нашей секретной информации.

Позвольте вам представить такой алгоритм.


В отличии от вышеназванных программ, я не храню пароль внутри зашифрованного файла. Шифр хранится отдельно. И вы сами должны позаботиться, чтобы в момент расшифровки он был именно тем, который был применен при шифровании исходного файла. В противном случае вы получите просто следующую реинкарнацию массива данных точно такой же длинны, но прочесть которую так же невозможно, как и первоначальный вариант, который вы получили. И никаких сообщений о том, что шифр НЕ ТОТ. Программа просто не знает, ТОТ он или НЕ ТОТ!!!

Теперь расскажу об алгоритмах шифрования, применённых мной в данном шифровальщике. Их три. Они применяются последовательно.

1. Сначала используется алгоритм замены: это когда каждому байту исходного файла ставится в соответствие байт с другим кодом. При этом размер шифрованных данных точно соответствует исходным. А порядок следования байтов друг за другом в файле не меняется.

2. Затем происходит перестановка байтов внутри групп. Порядок следования байтов нарушается, но размер шифрованных данных остаётся прежним.

3. А после этого на каждую группу накладывается маска шифра. При этом даже одинаковые символы, закодированные одним и тем же кодом, становятся разными. Но размер зашифрованных данных сохраняется первоначальным.

Расшифровка идёт в обратной последовательности.

Для всех операций шифрования и дешифровки используется файл шифра. Этот файл и составляет основную ценность всей затеи. Ибо, если у вас есть только зашифрованные данные, – расшифровать их невозможно. Если даже у вас есть исходный текст программ шифровальщика, при помощи которого были получены зашифрованные данные, то и в этом случае ситуация остаётся безнадёжной. Даже если у вас есть другой файл, зашифрованный этим же шифром, и есть исходный файл этого другого файла, то и в этом случае вы не получите никаких преимуществ. Возможно, лишь очень слабую тень надежды, что пользователь Шифровальщика допустил неосмотрительность (о которой я скажу ниже) и "подставился".

Если у вас нет исходного файла шифра, то получить его никаким способом не удастся, если пользователь принял соответствующие меры.



1. ПРЕДЕЛЫ ИСПОЛЬЗОВАНИЯ

Размер шифруемого файла не может превышать максимальный
размер типа LONG в Бейсике, т.е. 2147483647 байт – это принципиальный предел самого Бейсика, работающего в режиме DOS и самой операционной системы.
 
Однако, я сомневаюсь, что вам придётся шифровать архивы большего размера. Если же понадобится, то вспомните о том, что архиваторы умеют создавать многотомные архивы.



2. ПОРЯДОК РАБОТЫ


2.1. Сначала запускается генератор шифра. Это делается при помощи ключа /K, что означает KEY – ключ. Например так:

STORM /K MY.KEY

здесь /K – ключ генератора шифра, который создаёт файл шифра MY.KEY размером 256 байт, в котором последовательность кодов от 0 до 255 "рассыпана" случайным образом. Этот файл служит необходимым элементом для шифровки и расшифровки сообщения. Если файл шифра будет утерян, то расшифровать сообщение будет невозможно.


 +=====================================+
 | ХРАНИТЕ ФАЙЛ ШИФРА В НАДЁЖНОМ МЕСТЕ |
 +=====================================+


Обязательно необходимо помечать себе: каким шифром было зашифровано сообщение, иначе вы не будете знать, какой шифр передать своему адресату, чтобы он смог расшифровать ваше сообщение.



2.2. Шифрование выполняется при помощи ШИФРАТОРА. Для его запуска используется ключ /L, что означает Lock – запереть. Шифровать рекомендуется только архивированные данные, дабы не снизить криптографическую устойчивость шифровальщика.

Шифрование выполняется следующим образом, из командной строки выдаётся, например:

STORM /L MY.KEY ARHIV.ZIP ARHIV.CRP

Здесь /L – ключ шифратора, MY.KEY – файл шифра, сгенерированный на предыдущем шаге и который должен находиться в текущем каталоге, ARHIV.ZIP – исходный файл, который будет зашифрован, а ARHIV.CRP – выходной файл.

В результате будет создан новый файл ARHIV.CRP, по размеру точно совпадающий с исходным, но раскрыть который не имея файла шифра MY.KEY будет невозможно.


2.3. Обратное действие по расшифровке сообщения выполняется при помощи ДЕШИФРАТОРА. Для его запуска используется ключ /U, означающий UnLock – отпереть.

STORM /U MY.KEY ARHIV.CRP ARHIV.ZIP

Здесь /U – ключ дешифратора, MY.KEY – файл шифра, сгенерированный на предыдущих шагах и который должен находиться в текущем каталоге, ARHIV.CRP – исходный файл, который будет расшифрован, а ARHIV.ZIP – выходной файл.

После обработки в файле ARHIV.ZIP вы получите восстановленный архив.



3. ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ

В версии 4 введены дополнительные возможности по управлению алгоритмами шифратора и дешифратора. Теперь можно после ключа указать номер, который определяет набор алгоритмов, включаемых в работу.

Номер должен быть от 0 до 7.

Если разложить номер на биты, то видно, что младший бит включает ( = 1) или выключает ( = 0) алгоритм замены, средний бит отвечает за алгоритм перестановки, а старший бит за алгоритм наложения шифра.

Таким образом, номер равный 7 равносилен указанию ключа без номера – работают все три алгоритма, как обычно.
 
Номер 0 отключает все алгоритмы вовсе. Смысла в этом никакого, разве что использовать STORM.EXE в качестве альтернативы команды COPY.

Другие номера определяют комбинации алгоритмов.

Вы можете провести замену одним шифром, перемешивание вторым, а наложение третьим. Только не забудьте в какой последовательности вы это делали.



В частности, появилась интересная возможность использования алгоритма замены (ключи /L1 и /U1) для совсем других целей, явно не связанных с шифрованием. Если вы сами создадите файл шифра, в котором коды будут расставлены в нужном вам порядке, то при помощи шифровальщика вы можете выполнять перекодировку из различных таблиц кодировки в любые, например из DOS в Windows и обратно.
 Для демонстрации такой возможности я подправил файл шифра в отладчике и получил файл с именем dos-win.key .


Дав команду
STORM /L1 DOS-WIN.KEY READ-ME!.TXT READ-WIN.TXT ,
вы выполните перекодировку данной инструкции из DOS в Windows.


А команда
STORM /U1 DOS-WIN.KEY READ-WIN.TXT READ-ME!.TXT
выполнит для вас обратную перекодировку из Windows в DOS.


Стоит сохранить данный файл шифра (DOS-WIN.KEY) и запомнить, что шифрование (/L1) конвертирует текст в прямом направлении, как указано в имени шифра (DOS-WIN), а расшифровка (/U1) производит обратную операцию (WIN-DOS).



Ещё одно побочное применение шифровальщика с ключом /L1 (и только с ним!, так как обратное преобразование с ключом /U1 даёт нулевой результат). Сейчас объясню о чём идёт речь и почему так происходит.
 
Всем хорошо известна проблема русификации, когда по каким-либо причинам отсутствуют русские буквы, или техническая неисправность, или их и не было в помине изначально, а вам нужно прочитать русский текст, восстановив информацию из совершенно безобразных "краказябров".
 
Вот вам вполне приемлемое решение: смотрите файл RUS-LAT.KEY. Это отредактированный вручную в отладчике файл шифра, в котором схожие по начертанию или произношению русские буквы заменены на латинские. Это не заняло у меня много времени и получилась такая табличка:

а – A и – I р – R ш – W ё – E
б – B й – I с – S щ – W
в – V к – K т – T ъ – "
г – G л – L у – U ы – &
д – D м – M ф – F ь – '
е – E н – N х – X э – @
ж – J о – O ц – C ю – Q
з – Z п – P ч – H я – Y

(для наглядности русские буквы изображены маленькими, а латинские – большими).

Не буду настаивать на идеальности данной конструкции, однако отмечу тот факт, что в этой табличке удалось добиться отсутствия двухсимвольных сочетаний, а буквы ЛАТИНИЦЫ использованы полностью.
 
Ne budu nastaivat' na ideal'nosti dannoi konstrukcii, odnako otmehu tot fakt, hto v @toi tablihke udalos' dobit'sy otsutstviy dvuxsimvol'n&x sohetanii, a bukv& LATINIC& ispol'zovan& polnost'q.
 
А текст, как вы изволили видеть, прочесть можно...

Так вот, данный абзац был получен в результате выполнения того же Шифровальщика с файлом шифра RUS-LAT.KEY, на создание которого у меня ушло менее получаса. А команду я дал такую:

STORM /L1 RUS-LAT.KEY PROBA.TXT PROBA!.TXT

При этом ни что не мешает вам самим отредактировать файл шифра или создать собственный с нуля.

Почему обратное преобразование невозможно с данным файлом шифра? Потому что символы ЛАТИНИЦЫ в таблице кодировки стоят раньше, чем заменяемые символы КИРИЛИЦЫ. При выполнении прямого преобразования с ключом /L1 замена происходит, а при обратной замене с ключом /U1 вы получите точно тот же самый текст, что и был подан на вход команды.

Для обратного преобразования нужен другой файл шифра, в котором символы ЛАТИНИЦЫ были бы заменены на коды КИРИЛИЦЫ во всей таблице кодировки. Но тогда с ней будет тоже самое, что и с предыдущей. То есть – ключ /L1 даст свой положительный эффект, а ключ /U1 – ровно никакого.

Но что с того? Лишь бы результат был!

Вот такой командой можно отыграть назад. То есть использовать другой файл шифра:

STORM /L1 LAT-RUS.KEY PROBA!.TXT PROBA!!.TXT

Всё тот же абзац, восстановленный предыдущей командой, будет выглядеть так:

Не буду настаивать на идеальности даннои конструкции, однако отмечу тот факт, что в этои табличке удалось добиться отсутствия двухсимвольных сочетании, а буквы ЛАТИНИЦы использованы полностью.

Замечу, что в шифре LAT-RUS.KEY остался не заменённым твёрдый знак, так что он будет оставаться двойным апострофом. Исчезли буквы ё, й, щ. А такие буквы, как Э, Ы и Ь перестали быть строчными и прописными, – остались только строчные. И тем не менее результат имеет вполне приемлемое качество.

Однако вы не должны удивляться, когда вам встретиться незнакомое слово, например "Шиндошс"...


А теперь приведу список значений номеров алгоритмов, которые вы можете указывать после ключа:


ШИФРАТОР

/L1 – замена
/L2 – перестановка
/L3 – замена + перестановка
/L4 – наложение
/L5 – замена + наложение
/L6 – перестановка + наложение
/L7 – замена + перестановка + наложение (равносильно /L)


ДЕШИФРАТОР

/U1 – замена
/U2 – перестановка
/U3 – перестановка + замена
/U4 – наложение
/U5 – наложение + замена
/U6 – наложение + перестановка
/U7 – наложение + перестановка + замена (равносильно /U)



ПОЯСНЕНИЕ

Шифровать прямо текстовый документ не желательно. И вот почему. Так как размер выходного файла соответствует размеру входного, то становится ясно, что текст шифруется методом подстановки. То есть каждому байту (коду от 0 до 255) соответствует свой номер в таблице шифра. Несложно подсчитать количество возможных вариантов, которое надо перепробовать, чтобы взломать шифр: оно будет равно 256 * 255 * 254 ... * 3 * 2 , т.е. будет равно факториалу 256 !

То есть, для угадывания нужной комбинации таблицы подстановки из 256 байт нужно перебрать 256! таких вариантов. Много это или мало? Я попытался рассчитать на компьютере факториал 256, но компьютер дал переполнение на 170!, а полученное значение ушло за границу 1 * 10 в степени 300 с хвостиком. Если пробовать в секунду по миллиону таблиц (10^6), то потребуется 10^300 без хвостика...

Если вспомнить, что в одном тысячелетии всего около чуть более 10^10 секунд ( если быть более точным – 3,1536 * 10^10), то становится ясно, что за тысячу лет можно успеть перебрать более 3-х процентов от всего множества.

Позволю себе заметить, что речь идёт о факториале 170! а не 256! (!!!), так что надо ещё ввести поправочку ... Правда оценить размер этой поправочки довольно трудно.


Однако методы подстановки всегда считались уязвимыми, так как в них каждому символу соответствует свой, хотя и с другим номером. Достаточно применить метод частотного анализа и можно определить многие коды из самых распространённых букв алфавита и таким образом удастся свести число вариантов к приемлемому, которое рассчитать на компьютере не представит труда.

Поэтому, я советую шифровать заархивированный файл. Современные методы архивации так искажают исходный файл, выжимая из него "воду", что методы частотного анализа становятся неприменимы.


Полезно сравнить криптоустойчивость моего самодельного шифровальщика с названными выше стандартными продуктами защиты и все станет ясно. Если даже допустить, что в названии пароля можно использовать любые допустимые символы из всей таблицы ASCII (что конечно же не так, вы же не можете вставить в пароль Tab, Backspase, Enter и многие другие спец.символы, так что алфавит пароля ограничен символами, которые вы можете ввести с клавиатуры обычным порядком), но даже если считать, что в пароле возможно употребить всю таблицу ASCII, то тогда, чтобы сравниться по криптоустойчивости с данным шифровальщиком нужно будет вводить пароль длинной не менее 210 символов!


Откуда взялось это число? Сейчас объясню.

Если набор возможных символов пароля составляет A знаков, то число всех комбинаций из n символов будет равно A в степени n, так для 4-х значного пароля содержащего только цифры (вариант pin-кода на пластиковой карточке) число комбинаций будет 10 в степени 4, т.е. 10 000 штук. Именно по этому банкоматы допускают лишь три попытки для ввода pin-кода, если pin-код введён неверно и на третий раз, то карточка блокируется банкоматом – машина считает, что это не ваша карточка.

Я же проводил расчёт из поиска решения равенства:

256 ^ n = 256 ! , которое получается из предыдущего допущения о возможности вводить все символы из таблицы кодировки при наборе пароля.

n * ln (256) = ln (256 !)
n = [ ln(256) + ln(255) + ln(254) + ... + ln(2) ] / ln(256)

У меня получилось приблизительно n = 210,499536 , но т.к. число символов в пароле может быть только целым, то n = 210


Итак, чтобы обладать такой же криптографической устойчивостью, как и представленный вашему вниманию "самопальный" шифровальщик, пароль стандартных средств защиты данных должен быть длинной 210 символов.

Можете себе представить какой это НЕЛЁГКИЙ ТРУД ввести "звезданутый" (т.е. затенённый звёздочками) пароль из более чем ДВУХСОТ! символов...


В отличие от ввода пароля, как это принято в стандартных средствах, данная программа работает с внешним файлом шифра, который генерируется автоматически. Длинна его 256 символов. Правда создается он не за считанные мгновения (причину я оговорю ниже), а требует несколько минут в зависимости от быстродействия компьютера, и хранится, как любой другой файл, оставляя за пользователем право распорядиться им, как тому вздумается.


Одна интересная особенность вскрылась по ходу написания этого пояснения, и в результате модуль генерации шифра был существенно доработан. Вот в чём дело.

Шифр генерируется "случайным образом". (Я не зря поставил кавычки.) Работает генератор ПСЕВДО случайных чисел. Как это принято, начальное значение для инициализации генератора случайных чисел привязывают к таймеру.

RANDOMIZE TIMER

Если угадать значение TIMER, то можно было бы надеяться повторить генерацию таблицы шифра (имея конечно исходные тексты программ, дабы посмотреть, как это было произведено). Но ведь сам зашифрованный файл несёт в себе информацию о дате и главное ВРЕМЕНИ своего создания! Если вы за несколько секунд до его шифрования сгенерировали сам шифр, то вот вам и подсказка, которая сжимает диапазон возможных значений для перебора! Вот эту подсказку надо обязательно убрать.
 
В принципе, достаточно всего лишь использовать заранее заготовленный файл шифра. И тогда вашему врагу не достанется даже малая толика подсказки!

Не буду изображать, что мне самому всё ясно в данном шифровальщике. Например, для меня остаётся открытым вопрос: "Если начальное значение TIMER однозначно определяет генерируемый шифр, то куда деваются остальные возможные варианты шифра, которых должно быть, как мы уже выяснили 256!, но любому посвященному человеку ясно, что число тиков в сутках значительно меньше?"

(Значение TIMER равно числу тиков прошедших с полуночи по
внутренним часам компьютера. 1 секунда – это 18,2 тика. Понятно,
что в сутках их будет 24 * 3600 * 18,2 = 1 572 480.)

 . . .

Тут автор глубоко задумался, а потом модифицировал программу генератора шифра. Теперь процесс генерации длится несколько минут, а шифр носит действительно случайный характер, т.к. в процессе генерации шифра совсем не используется генератор псевдо случайных чисел.
 
В предыдущей версии 4.1 он использовался с холостым циклом, но после тщательного изучения я пришел к выводу, что видимо ГСЧ функция в принципе не способна дать возможность выбора шифра из 256! (факториал) значений.
 
Я не буду подробно разбирать метод генерации, скажу лишь, что и на быстрых и на медленных компьютерах процесс генерации шифра идет теперь с одинаковым темпом и занимает приблизительно 10 минут. Попытки же угадывания значения таймера перед генерацией шифра совершенно потеряли всякий смысл, а множество возможных шифров действительно составляет 256!


Ещё одно немаловажное обстоятельство.

Какой бы стандартный архиватор вы не использовали для предварительного сжатия текста, он расположит внутри архива свой заголовок. Если собрать все распространенные архиваторы, то можно составить набор таких заголовков и попытаться угадать методом перебора – какой же из них был использован для сжатия?

Если злоумышленник знает ваши пристрастия, то у него появляется дополнительная информация, которую можно использовать для расшифровки (не забывайте, что любое количество шифрований методом подстановки всего лишь меняет одни коды символов на другие, а порядок следования сохраняется).

Уйти от этого недостатка может помочь только перемешивание байт в файле словно карт в колоде по правилу, задаваемому тем же файлом шифра. Именно это реализовано во втором методе шифровальщика. (В помощи этот алгоритм назван "перестановкой".)


И последнее важное замечание, которое прояснит ситуацию, упомянутую мной вначале, как "слабая тень надежды, что пользователь Шифровальщика допустил неосмотрительность и "подставился".

Всё сказанное мной о шифровальщике будет верно до тех пор, пока злоумышленник не получит исходный и выходной файлы шифрованных данных, в которых найдётся 256 идущих подряд одинаковых символов.

Почему? Поясняю.

Представьте, что в начале текстового файла находится 256 пробелов. Тогда при замене пробел будет закодирован некоторым другим кодом, и пробелом быть уже перестанет. На следующем шаге шифрования программа перемешает группу из 256 байт согласно правилу, получаемому из файла шифра. Но так как все коды одинаковые, то переставляй, не переставляй их, результат всё тот же. Остаётся последний эшелон обороны – третий метод – наложение маски шифра.

Однако если у злоумышленника будет не только зашифрованный файл, но и исходный файл данных (речь идёт не о файле, который он пытается "вскрыть" – если бы этот файл был в наличии, то все вопросы отпали – это понятно, а о дополнительных данных, которые были получены при помощи того же самого файла шифра, которым зашифрована нужная секретная информация), тогда он увидит, что вначале текста стоят стеной пробелы и сообразит, что нужно перебрать 256 вариантов чтобы получить нужный шифр. Так как несложно догадаться, что наложение маски шифра на один и тот же код даёт всего лишь сдвиг шифра на данной группе байтов. Отняв этот сдвиг с отпечатка шифра на данном участке, шифр будет найден, и шифровальщик будет вынужден капитулировать перед врагом. А ваши данные будут наградой злодею за проявленную находчивость.


Чтобы этого не произошло, нужно:


1. Шифруйте архивированные файлы. Ибо для них 256 одинаковых символов подряд – это непозволительная роскошь.

или

2. Пользуйтесь разными файлами шифров.

или

3. Берегите так исходные данные, чтобы ни один файл содержащий группу одинаковых символов длинною 256 шт. не достался врагу вместе со своим зашифрованным отображением.


О том, что файл шифра должен находиться в недоступном для чужих рук месте, я уже не говорю, как о само собой разумеющемся.


По сути дела, усилия пользователя по составлению и запоминанию пароля заменены запоминанием имени файла шифра и его местоположения. Если вы подумаете, что вместо одного зашифрованного файла вам придётся носить с собой ещё и файл шифра в электронном виде вкупе с программой шифрования, то смею вас заверить – накладные расходы увеличиваются не намного, зато надёжность возрастает не в разы, и даже не на порядки! Использование данного шифровальщика, с соблюдением всех мер предосторожности оговоренных мною в данном руководстве, делает вашу информацию ПРИНЦИПИАЛЬНО НЕУЯЗВИМОЙ и выводит вашу личную свободу (а что есть право человека на частную жизнь, как не его свобода!) на качественно иной уровень.



17.02.2006
01:23



Далее приведён листинг программы для Quick Basic v 4.5 .



'??????????????????????????????????????
'?     Шифровальщик "ШТОРМ" v 5.0     ?
'??????????????????????????????????????
DECLARE SUB MESHAY (Ukz!, Siz!)      'Перемешать
DECLARE SUB NALOJENIE (Ukz!, Siz!)   'Наложить шифр
DECLARE SUB REMESHAY (Ukz!, Siz!)    'Сложить (обратное "перемешать")
DECLARE SUB RENALOJENIE (Ukz!, Siz!) 'Снять наложение
DECLARE SUB REZAMENA (Ukz!, Siz!)    'Восстановить (обратное "замена")
DECLARE SUB WorkBuf ()               'Обработать буфер
DECLARE SUB ZAMENA (Ukz!, Siz!)      'Замена
DECLARE SUB GENERATOR ()             'Генератор шифра
DECLARE SUB SHIFRATOR ()             'Шифратор-Дешифратор
DECLARE SUB READSHIFR ()             'Прочесть шифр из файла
DECLARE SUB PARCOM (a$, c$, k%)      'Выделить из ком.стр. параметр
DECLARE SUB VERIFYFILE (c$, k%)      'Проверить существование файла c$
DECLARE SUB PROCENT (Ukazatel&)      'Прогрессор в %-тах

COMMON SHARED BufferSize, ShifrSize, shifr$, buffer$, M1&
COMMON SHARED FIL1$, FIL2$, FIL3$, MyKey%, MyCommand$
COMMON SHARED Progress%, OneProcent&, TenProcent&

Progress% = 0                'Начальное значение прогрессора 0%-тов
BufferSize = 8192                'Длинна буфера 8k
ShifrSize = 256                'Длинна шифра 0.25k
shifr$ = STRING$(ShifrSize, 0)     'Создать строку для шифра

IF COMMAND$ = "" THEN GOTO Help
MyCommand$ = UCASE$(COMMAND$)      'Преобразовать в прописные
CALL PARCOM(MyCommand$, a$, k%)    'Выделить из ком.стр. 1-ый параметр
IF a$ = "/H" THEN GOTO HelpRUS
IF a$ = "" OR k% = 0 THEN GOTO Help
CALL PARCOM(MyCommand$, FIL1$, k%) 'Выделить следующий параметр
IF FIL1$ = "" THEN GOTO Help

'Разобрать ключ
IF a$ = "/K" THEN
'Проверить, что FIL1$ несуществует, иначе выдать сообщение
CALL VERIFYFILE(FIL1$, k%)
IF k% = -1 THEN GOTO KONEC
IF k% = 0 THEN GOTO Gener
IF k% = 1 THEN GOTO METKA10
ELSE
IF k% = 0 THEN GOTO Help
CALL PARCOM(MyCommand$, FIL2$, k%) 'Выделить следующий параметр
IF FIL2$ = "" OR k% = 0 THEN GOTO Help
CALL PARCOM(MyCommand$, FIL3$, k%) 'Выделить следующий параметр
IF FIL3$ = "" OR FIL2$ = FIL3$ THEN GOTO Help

'Проверить, что FIL1$ существует, иначе выдать сообщение
CALL VERIFYFILE(FIL1$, k%)
IF k% < 0 THEN GOTO KONEC
IF k% = 0 THEN GOTO METKA13 'Нет файла шифра FIL1$

'Проверить, что FIL2$ существует, иначе выдать сообщение
CALL VERIFYFILE(FIL2$, k%)
IF k% < 0 THEN GOTO KONEC
IF k% = 0 THEN GOTO METKA15 'Нет входного файла FIL2$

'Проверить, что FIL3$ несуществует, иначе выдать сообщение
CALL VERIFYFILE(FIL3$, k%)
IF k% < 0 THEN GOTO KONEC
IF k% = 1 THEN GOTO METKA20 'Выходной файл FIL3$ уже есть

'Разобрать ключ для Lock или UnLock
k% = LEN(a$)
IF k% < 2 OR k% > 3 THEN GOTO METKA25 'Неверный ключ
IF LEFT$(a$, 2) = "/L" THEN
MyKey% = 8
ELSEIF LEFT$(a$, 2) = "/U" THEN
MyKey% = 0
ELSE
GOTO METKA25 'Неверный ключ
END IF

IF k% = 3 THEN
k% = ASC(RIGHT$(a$, 1))
   IF k% >= ASC("0") AND k% <= ASC("7") THEN
   MyKey% = MyKey% + VAL(RIGHT$(a$, 1))
   ELSE
   GOTO METKA25 'Неверный ключ
   END IF
ELSE
MyKey% = MyKey% + 7
END IF
GOTO MyLock 'Запустить ШИФРАТОР-ДЕШИФРАТОР

END IF

Help:
CLS
PRINT PRINT "?                Program cipher "; CHR$(34); "STORM"; CHR$(34);
PRINT " v 5.0                ?"
PRINT "?                (C)                2008                ?"
PRINT "?                ?"
PRINT "?      Format command line for run program                ?"
PRINT "?                ?"
PRINT "?      RUS Help   :                ?"
PRINT "?      STORM /H                ?"
PRINT "?                ?"
PRINT "?      Creat file of cipher   :                ?"
PRINT "?      STORM /K MY.KEY                ?"
PRINT "?                ?"
PRINT "?      To cipher by file  MY.KEY  archives  ARHIV.ZIP, and result  ?"
PRINT "? chiper output in the file  ARHIV.CRP  :                ?"
PRINT "?      STORM  /L  MY.KEY  ARHIV.ZIP  ARHIV.CRP                ?"
PRINT "?                ?"
PRINT "?      To decipher by file  MY.KEY  file  ARHIV.CRP  , and result  ?"
PRINT "? output in the file  ARHIV.ZIP  :                ?"
PRINT "?      STORM  /U  MY.KEY  ARHIV.CRP  ARHIV.ZIP                ?"
PRINT "?                ?"
PRINT "?      See also  READ-ME!.TXT  for the detail information  .       ?"
PRINT DO: LOOP WHILE INKEY$ = ""
GOTO KONEC

HelpRUS:
CLS
PRINT PRINT "?             Программа шифровальщик "; CHR$(34); "ШТОРМ"; CHR$(34);
PRINT " v 5.0                ?"
PRINT "?                (C)                2008                ?"
PRINT "?                ?"
PRINT "?      Формат командной строки для запуска программы               ?"
PRINT "?                ?"
PRINT "?      Помощь:                ?"
PRINT "?      STORM /H                ?"
PRINT "?                ?"
PRINT "?      Создать файл шифра:                ?"
PRINT "?      STORM /K MY.KEY                ?"
PRINT "?                ?"
PRINT "?      Зашифровать шифром  MY.KEY  архив  ARHIV.ZIP  , а результат ?"
PRINT "? шифрования вывести в файл  ARHIV.CRP  :                ?"
PRINT "?      STORM  /L  MY.KEY  ARHIV.ZIP  ARHIV.CRP                ?"
PRINT "?                ?"
PRINT "?      Расшифровать шифром  MY.KEY  файл  ARHIV.CRP  , а результат ?"
PRINT "? вывести в файл  ARHIV.ZIP  :                ?"
PRINT "?      STORM  /U  MY.KEY  ARHIV.CRP  ARHIV.ZIP                ?"
PRINT "?                ?"
PRINT "?      Подробное описание в файле READ-ME!.TXT                ?"
PRINT DO: LOOP WHILE INKEY$ = ""
CLS
PRINT PRINT "?             Программа шифровальщик "; CHR$(34); "ШТОРМ"; CHR$(34);
PRINT " v 5.0                ?"
PRINT "?                (C)                2008                ?"
PRINT "?                ?"
PRINT "?      Дополнительные возможности управления алгоритмами           ?"
PRINT "?                ?"
PRINT "?    /L1 - замена ?????????????????????? ШИФРАТОР ??????????????   ?"
PRINT "?    /L2 - перестановка                ?   ?"
PRINT "?    /L3 - замена + перестановка                ?   ?"
PRINT "?    /L4 - наложение                ?   ?"
PRINT "?    /L5 - замена + наложение                ?   ?"
PRINT "?    /L6 - перестановка + наложение                ?   ?"
PRINT "?    /L7 - замена + перестановка + наложение (равносильно /L) ??   ?"
PRINT "?                ?"
PRINT "?    /U1 - замена ?????????????????????? ДЕШИФРАТОР ????????????   ?"
PRINT "?    /U2 - перестановка                ?   ?"
PRINT "?    /U3 - перестановка + замена                ?   ?"
PRINT "?    /U4 - наложение                ?   ?"
PRINT "?    /U5 - наложение + замена                ?   ?"
PRINT "?    /U6 - наложение + перестановка                ?   ?"
PRINT "?    /U7 - наложение + перестановка + замена (равносильно /U) ??   ?"
PRINT DO: LOOP WHILE INKEY$ = ""
GOTO KONEC

METKA10:
PRINT ""
PRINT "Внимание! Файл шифра с именем "; FIL1$; " уже есть."
PRINT "Чтобы не потерять его, придумайте другое имя,"
PRINT "или переименуйте существующий."
PRINT ""
GOTO KONEC

METKA13:
PRINT ""
PRINT "Внимание! Файл шифра с именем "; FIL1$; " не найден."
PRINT "Проверьте правильно ли указано имя файла."
PRINT ""
GOTO KONEC

METKA15:
PRINT ""
PRINT "Внимание! Входной файл с именем "; FIL2$; " не найден."
PRINT "Проверьте правильно ли указано имя файла."
PRINT ""
GOTO KONEC

METKA20:
PRINT ""
PRINT "Внимание! Выходной файл с именем "; FIL3$; " уже есть."
PRINT "Чтобы не потерять его, придумайте другое имя,"
PRINT "или переименуйте существующий."
PRINT ""
GOTO KONEC

METKA25:
PRINT ""
PRINT "Внимание! Указан неверный ключ в командной строке."
PRINT ""
GOTO KONEC

Gener:
CALL GENERATOR
GOTO KONEC

MyLock:
CALL SHIFRATOR
GOTO KONEC

KONEC:
SYSTEM
END

SUB GENERATOR
'???????????????????????????????
'?       Генератор ШИФРА       ?
'???????????????????????????????
'Линейки-сопровождения к основному буферу
buf2$ = STRING$(256, 0) 'старший разряд метки
buf3$ = STRING$(256, 0) 'средний разряд метки
buf4$ = STRING$(256, 0) 'младший разряд метки

'Заполнить числами-метками линейки сопровождения
FOR i% = 1 TO 256
c$ = RTRIM$(LTRIM$(STR$(i%)))
IF LEN(c$) = 1 THEN c$ = "00" + c$
IF LEN(c$) = 2 THEN c$ = "0" + c$
MID$(buf2$, i%, 1) = MID$(c$, 1, 1) 'старший разряд метки
MID$(buf3$, i%, 1) = MID$(c$, 2, 1) 'средний разряд метки
MID$(buf4$, i%, 1) = MID$(c$, 3, 1) 'младший разряд метки
NEXT i%

CLS
LOCATE 7, 22
PRINT "Идет процесс генерации шифра."

FOR i% = 1 TO 255
GOSUB GENERDUB
'Вычислить позицию в буфере
l% = VAL(MID$(buf2$, j%, 1)) * 100
l% = l% + VAL(MID$(buf3$, j%, 1)) * 10 + VAL(MID$(buf4$, j%, 1))
MID$(shifr$, l%, 1) = CHR$(i%) 'Поставить код в буфер на эту позицию
'Вычеркнуть данную метку из множества линеек сопровождения
buf2$ = LEFT$(buf2$, j% - 1) + RIGHT$(buf2$, LEN(buf2$) - j%)
buf3$ = LEFT$(buf3$, j% - 1) + RIGHT$(buf3$, LEN(buf3$) - j%)
buf4$ = LEFT$(buf4$, j% - 1) + RIGHT$(buf4$, LEN(buf4$) - j%)
GOSUB PROCENT
NEXT i%

LOCATE 19, 34
PRINT INT(i% * 100 / 256); "%" 'сообщение о 100% (завершении) процесса

'Сохранение шифра в виде файла
OPEN FIL1$ FOR BINARY AS #1
PUT #1, 1&, shifr$
CLOSE #1
EXIT SUB

'Получить случайное значение n% [от 1 до 256] за 2 сек
GENERDUB:
GOSUB MYGENRND
n% = 16 * k%
GOSUB MYGENRND
n% = n% + k% + 1

'Отмасштабировать по линейке случайное n%
par1# = LEN(buf2$)
par2# = n%
par3# = par1# * par2# / 256#
j% = FIX(par3#)
IF j% = 0 THEN j% = 1
RETURN

'Получить случайное значение k% [от 0 до 15] за 1 сек
MYGENRND:
p& = 2 ^ 31 - 1
t& = 0
Oldt# = TIMER
DO
IF t& >= p& THEN
t& = 0
ELSE
t& = t& + 1
END IF
LOOP WHILE TIMER < Oldt# + 1#
k% = VAL(STR$(&HF& AND t&))
LOCATE 13, 32
PRINT TIME$
RETURN

PROCENT:
LOCATE 13, 32
PRINT TIME$
LOCATE 19, 34
PRINT INT(i% * 100 / 256); "%" 'вывести сообщение о процессе
RETURN

END SUB

SUB MESHAY (Ukz, Siz) 'режим ПЕРЕМЕШИВАНИЯ
'Шифрование перемешиванием
temp$ = STRING$(Siz, 0)
n% = 1
FOR i% = 1 TO ShifrSize
k% = ASC(MID$(shifr$, i%, 1))
IF k% < Siz THEN
MID$(temp$, n%, 1) = MID$(buffer$, k% + Ukz, 1)
n% = n% + 1
END IF
NEXT i%
MID$(buffer$, Ukz, Ukz + Siz - 1) = temp$
END SUB

SUB NALOJENIE (Ukz, Siz) 'режим НАЛОЖЕНИЯ
'Шифрование наложением
FOR i% = Ukz TO Ukz + Siz - 1
T1% = ASC(MID$(buffer$, i%, 1))
T2% = ASC(MID$(shifr$, i% - Ukz + 1, 1))
T0% = &HFF AND (T1% + T2%)
MID$(buffer$, i%, 1) = CHR$(T0%)
NEXT i%
END SUB

SUB PARCOM (D$, c$, k%) 'Выделить из ком.стр. 1-ый параметр
'Входной параметр
'D$ - командная строка
'Выходные параметры
'D$ - командная строка без первого параметра
'c$ - первый параметр
'k% - осталось символов в командной строке

dlcom% = LEN(D$)

'Исключить из D$ начальные пробелы
DO WHILE INSTR(1, D$, " ") = 1
dlcom% = dlcom% - 1
IF dlcom% = 0 THEN
D$ = ""
ELSE
D$ = RIGHT$(D$, dlcom%)
END IF
LOOP

k% = INSTR(1, D$, " ")
IF k% = 0 THEN
c$ = D$
D$ = ""
ELSE
c$ = LEFT$(D$, k% - 1)
D$ = RIGHT$(D$, dlcom% - k%)
k% = LEN(D$)
END IF
END SUB

SUB PROCENT (Ukazatel&) 'Прогрессор в %-тах
'Определить насколько увеличился Ukazatel& от предыдущего раза
TempU& = Ukazatel& - (Progress% * OneProcent&)

'Набрать прирост Ukazatel& десятью %-тами
WHILE TempU& > TenProcent&
TempU& = TempU& - TenProcent&
Progress% = Progress% + 10
WEND

'Набрать прирост Ukazatel& одним %-том
WHILE TempU& > OneProcent&
TempU& = TempU& - OneProcent&
Progress% = Progress% + 1
WEND

END SUB

SUB READSHIFR 'Прочесть шифр из файла
OPEN FIL1$ FOR BINARY AS #1
GET #1, 1&, shifr$
CLOSE #1
END SUB

SUB REMESHAY (Ukz, Siz) 'режим ПЕРЕМЕШИВАНИЯ
'Расшифровка после перемешивания
temp$ = STRING$(Siz, 0)
n% = 1
FOR i% = 1 TO ShifrSize
k% = ASC(MID$(shifr$, i%, 1))
IF k% < Siz THEN
MID$(temp$, k% + 1, 1) = MID$(buffer$, n% + Ukz - 1, 1)
n% = n% + 1
END IF
NEXT i%
MID$(buffer$, Ukz, Ukz + Siz - 1) = temp$
END SUB

SUB RENALOJENIE (Ukz, Siz) 'режим НАЛОЖЕНИЯ
'Расшифровка после наложения
FOR i% = Ukz TO Ukz + Siz - 1
T1% = ASC(MID$(buffer$, i%, 1))
T2% = ASC(MID$(shifr$, i% - Ukz + 1, 1))
T0% = &HFF AND (T1% - T2%)
MID$(buffer$, i%, 1) = CHR$(T0%)
NEXT i%
END SUB

SUB REZAMENA (Ukz, Siz) 'режим ЗАМЕНА
FOR i% = Ukz TO Ukz + Siz - 1
'расшифровать
MID$(buffer$, i%, 1) = CHR$(INSTR(1, shifr$, MID$(buffer$, i%, 1)) - 1)
NEXT i%
END SUB

SUB SHIFRATOR
'????????????????????????????????????????????????????????
'?       Ш И Ф Р А Т О Р   --   Д Е Ш И Ф Р А Т О Р     ?
'????????????????????????????????????????????????????????

CALL READSHIFR 'Прочесть шифр из файла
buffer$ = STRING$(BufferSize, 0) 'Буфер обработки

'Открыть входной файл
OPEN FIL2$ FOR BINARY AS #1
Ukazatel& = 1& 'установить указатель на начало
lfil& = LOF(1) 'измерить длинну
IF lfil& = 0 THEN GOTO METKA0 'файл пуст -- выход

'Произвести расчёт
OneProcent& = lfil& / 100& 'Один процент от размера файла
TenProcent& = lfil& / 10&  'Десять процентов от размера файла
N1& = lfil& \ BufferSize   'число целых буферов в файле
M1& = lfil& MOD BufferSize 'остаток файла
MyRow% = CSRLIN 'получить текущую строку вывода на экран

'Открыть выходной файл
OPEN FIL3$ FOR BINARY AS #2

FOR i& = 1 TO N1& 'прочесть целое число буферов N1& из файла
GET #1, Ukazatel&, buffer$ 'прочесть очередной буфер из вх.ф
CALL WorkBuf 'обработка буфера
PUT #2, Ukazatel&, buffer$ 'записать обработанный буфер в вых.ф
Ukazatel& = Ukazatel& + BufferSize 'продвинуть указатель вперёд

'Подсчитать процент обработки
CALL PROCENT(Ukazatel&)

'Вывести процент обработки
LOCATE MyRow%, 1
PRINT USING "####"; Progress%;
PRINT " %";

NEXT i&

'Если остаток файла не ноль
IF M1& > 0 THEN 'то обработать его

'Реформировать буфер обработки под остаток
buffer$ = STRING$(M1&, 0)
GET #1, Ukazatel&, buffer$ 'прочесть M1& байт из файла
CALL WorkBuf 'обработка буфера
PUT #2, Ukazatel&, buffer$ 'записать обработанный буфер в вых.ф
END IF

'Вывести 100%
LOCATE MyRow%, 1
PRINT " 100 %"

CLOSE #2

METKA0:
CLOSE #1

END SUB

SUB VERIFYFILE (c$, k%) 'Проверить существование файла c$
a$ = "IF NOT EXIST " + c$ + " ECHO NO " + c$ + ">TEMP1.QBS"
SHELL a$
a$ = "IF EXIST " + c$ + " ECHO YES " + c$ + ">>TEMP1.QBS"
SHELL a$
OPEN "TEMP1.QBS" FOR INPUT AS #1
LINE INPUT #1, a$
CLOSE #1
KILL "TEMP1.QBS"
k% = INSTR(1, a$, c$)
IF k% > 0 THEN
k% = INSTR(1, a$, "NO")
IF k% > 0 THEN k% = 0 'Признак отсутствия
k% = INSTR(1, a$, "YES")
IF k% > 0 THEN k% = 1 'Признак существования
ELSE
k% = -1 'Признак ошибки
END IF
END SUB

SUB WorkBuf 'Обработать буфер
Ul = 1 'Начальная позиция в буфере

IF LEN(buffer$) = BufferSize THEN
'работаем с целым буфером

N2 = BufferSize \ ShifrSize   'число целых шифров в буфере
M2 = BufferSize MOD ShifrSize 'остаток буфера

FOR j = 1 TO N2 'обработать буфер шифром N2 раз
IF (MyKey% AND &H8) > 0 THEN 'работает ШИФРАТОР
IF (MyKey% AND &H1) > 0 THEN CALL ZAMENA(Ul, ShifrSize) 'сделать замену
IF (MyKey% AND &H2) > 0 THEN CALL MESHAY(Ul, ShifrSize) 'перемешать
IF (MyKey% AND &H4) > 0 THEN CALL NALOJENIE(Ul, ShifrSize) 'наложить шифр
ELSE 'работает ДЕШИФРАТОР
'снять наложение шифра
IF (MyKey% AND &H4) > 0 THEN CALL RENALOJENIE(Ul, ShifrSize)

IF (MyKey% AND &H2) > 0 THEN CALL REMESHAY(Ul, ShifrSize) 'составить
IF (MyKey% AND &H1) > 0 THEN CALL REZAMENA(Ul, ShifrSize) 'сделать замену
END IF
Ul = Ul + ShifrSize
NEXT j
IF M2 > 0 THEN 'обработать остаток буфера M2 байт
IF (MyKey% AND &H8) > 0 THEN 'работает ШИФРАТОР
IF (MyKey% AND &H1) > 0 THEN CALL ZAMENA(Ul, M2) 'сделать замену
IF (MyKey% AND &H2) > 0 THEN CALL MESHAY(Ul, M2) 'перемешать
IF (MyKey% AND &H4) > 0 THEN CALL NALOJENIE(Ul, M2) 'наложить шифр
ELSE 'работает ДЕШИФРАТОР

'снять наложение шифра
IF (MyKey% AND &H4) > 0 THEN CALL RENALOJENIE(Ul, M2)

IF (MyKey% AND &H2) > 0 THEN CALL REMESHAY(Ul, M2) 'составить
IF (MyKey% AND &H1) > 0 THEN CALL REZAMENA(Ul, M2) 'сделать замену
END IF
END IF

ELSE
'работаем с остатком буфера

N3 = M1& \ ShifrSize   'число целых шифров в остатке файла
M3 = M1& MOD ShifrSize 'остаток шифра от остатка файла

FOR j = 1 TO N3 'обработать остаток файла шифром N3 раз
IF (MyKey% AND &H8) > 0 THEN 'работает ШИФРАТОР
IF (MyKey% AND &H1) > 0 THEN CALL ZAMENA(Ul, ShifrSize) 'сделать замену
IF (MyKey% AND &H2) > 0 THEN CALL MESHAY(Ul, ShifrSize) 'перемешать
IF (MyKey% AND &H4) > 0 THEN CALL NALOJENIE(Ul, ShifrSize) 'наложить шифр
ELSE 'работает ДЕШИФРАТОР

'снять наложение шифра
IF (MyKey% AND &H4) > 0 THEN CALL RENALOJENIE(Ul, ShifrSize)

IF (MyKey% AND &H2) > 0 THEN CALL REMESHAY(Ul, ShifrSize) 'составить
IF (MyKey% AND &H1) > 0 THEN CALL REZAMENA(Ul, ShifrSize) 'сделать замену
END IF
Ul = Ul + ShifrSize
NEXT j
IF M3 > 0 THEN 'обработать остаток M3 байт
IF (MyKey% AND &H8) > 0 THEN 'работает ШИФРАТОР
IF (MyKey% AND &H1) > 0 THEN CALL ZAMENA(Ul, M3) 'сделать замену
IF (MyKey% AND &H2) > 0 THEN CALL MESHAY(Ul, M3) 'перемешать
IF (MyKey% AND &H4) > 0 THEN CALL NALOJENIE(Ul, M3) 'наложить шифр
ELSE 'работает ДЕШИФРАТОР

'снять наложение шифра
IF (MyKey% AND &H4) > 0 THEN CALL RENALOJENIE(Ul, M3)

IF (MyKey% AND &H2) > 0 THEN CALL REMESHAY(Ul, M3) 'составить
IF (MyKey% AND &H1) > 0 THEN CALL REZAMENA(Ul, M3) 'сделать замену
END IF
END IF

END IF
END SUB

SUB ZAMENA (Ukz, Siz) 'режим ЗАМЕНА
FOR i% = Ukz TO Ukz + Siz - 1
'зашифровать
MID$(buffer$, i%, 1) = MID$(shifr$, ASC(MID$(buffer$, i%, 1)) + 1, 1)
NEXT i%
END SUB




Ссылка для скачивания:
http://narod.ru/disk/26293422000/STORM5.zip.html

Формат ZIP, размер 53,5Кб (54838байт), внутри находятся файлы:


Имя файла       Размер         Контр.сум. CRC32*
------------------------------------------------
DOS-WIN.KEY  --    256 байт -- 2A242922
LAT-RUS.KEY  --    256 байт -- 8BD04E7E
READ-ME.TXT  -- 22 350 байт -- 8DB7E1D7
RUS-LAT.KEY  --    256 байт -- 3FF62173
STORM5.BAS   -- 18 935 байт -- F7F9FF54
STORM5.EXE   -- 55 420 байт -- DAA39B68

* -- CRC32 получена WinRAR 3.41


Назначение этих файлов:

DOS-WIN.KEY  -- таблица перекодировки из DOS в Win и обратно из Win в DOS.

LAT-RUS.KEY  -- таблица транслитерации из Лат. в Рус.

READ-ME.TXT -- Подробная инструкция пользователя.

RUS-LAT.KEY  -- таблица транслитерации из Рус. в Лат.

STORM5.BAS   -- исходный текст (комментарии в ДОС кодировке).

STORM5.EXE   -- сама программа в EXE-формате.



P.S. Архив будет храниться по приведённой ссылке 3 месяца.


20:01:36 19.10.2010


Рецензии