Взлом шифра Цезаря часть 2.
Итак приступим компилируем наш "кодировщик" Crypt запускаем и вводим любой текст для шифрования,я взял к примеру фразу "Our world is abstraction" и ключ key=26 вот что у нас выходит:
}C@ EY@ZV [E WPEFDSUF_]X
Откроем файл result.txt где сохранили шифротекст и будем думать как его взломать,а долго не будем думать а лучше прочитаем
"Прикладную криптографию" Брюса Шнайера.
Не буду выдумывать и перефразировывать Брюса Шнайера а просто его процитирую:
"Предположим,что открытый текст использует английский язык.Более того,пусть длина ключа любое небольшое число байт.Ниже описано,как взломать этот шифр:
1.Определим длину ключа с помощью процедуры,известной как ПОДСЧЕТ СОВПАДЕНИЙ.
Применим операцию XOR к шифротексту,используя в качестве ключа сам шифротекст с различными смещениями,и подсчитаем совпадающие байты. Если величина смещения кратна длине ключа,то совпадет свыше 6 процентов байтов. Если нет,то будут совпадать меньше чем 0.4 процента( считая,что обычный ASCII текст кодируется случайным ключом,для других типов открытых текстов числа будут другими). Это называется показателем совпадений. Минимальное смещение от одного значения,кратного длине ключа,к другому и есть длина ключа.
2. Сместим шифротекст на эту длину и проведем операцию XOR для смещенного и оригинального шифротекстов.Результатом операции будет удаление ключа и получение открытого текста,подвергнутого операции XOR с самим собой,смещенным на длину ключа. Так как в английском языке на один байт приходится 1.3 бита действительной информации,существующая значительная избыточность позволяет определить способ шифрования."
После многочисленных экспериментов я обнаружил одну маааленькую "неточность" которая делала эксперименты не совсем объективными.
Дело в том что просматривая различные проекты различных авторов находим все возможные модификации шифра цезаря,которые как можно понять
ограничиваются только фантазией и задумкой автора. Возможно я и ошибаюсь но мне кажется что в древней системе шифрования врят ли было допустимо использование
спецвимволов ]{_ + псевдографические символы эпохи ms-dos как в этом шифротексте }C@ EY@ZV [E WPEFDSUF_]X .
Проще говоря захотелось мне использовать только буквы алфавита и ничего более.
Вот к примеру посмотрим на не точность (которая вкралась в программу Crypt) которая искажает стандартный
шифр Цезаря вместо ключа key=3 ключ получается равным 3333333... исправим эту не точность
удалим этот цикл:
for i := 0 to (length(text) div length(key)) do
longkey := longkey + key;
а внутри другого цикла исправим longkey на кey
toto := chr((ord(text[i]) XOR ord(key[i])))
Проверяем и опять получаем туже ситуацию хоть и поменьше,что бы понять в чем "ошибка" посмотрим на таблицу всех символов и их кодов
для этого напишем маленькую программку
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, classes, windows;
var s:tstringlist; st:string; i:integer;
begin
s:=tstringlist.Create; // Создаем список строк
for i:=1 to 1000 do
st:=st+' '+inttostr(i)+'= '+char(ord(i))+#13; // пишем в одну строку код символа = символ+перенос на следующую строку
s.Add(st); // добавляем строку в список
s.SaveToFile('c:\chars.txt'); // сохраняем список в файл
s.Free; // уничтожаем список
winexec(pchar('c:\windows\notepad.exe c:\chars.txt'),sw_show); // что бы вручную не открывать сделаем это автоматически
end.
Желательно прописывать блокнот который поддерживает форматирование,а то выйдет не читабельно.
И вот что мы получаем большие символы английского начинаются с 65 по 90 малые с 97...122 русские с 128...175 и 224...239
Все остальные находящиеся в промежутках нужно вырезать т.е делать обработку после шифрования или что еще лучше внести в код
поправку которая будет не принимать лишний мусор.
На практике запускаем Crypt берем строчку из шифра и применяем ее в качестве пароля к целому шифротексту смотрим на результат
небольшая поправочка что бы программа не затерла шифротекст внесем еще изменения (либо просто переименуйте файл result.txt)
удалим вот эти строки из кода они нам уже не понадобятся
if c in ['Y','y'] then begin
AssignFile(F,'result.txt');
Rewrite(F);
Напишим новые
if fileexists(f) then renamefile(oldname,oldname);
Можно придумать любую модификацию имени,добавлять к имени result порядковый номер
или время ну или конечно свой вариант какой прийдет в голову.
Теперь у нас будет масса файлов что тоже не хорошо,винт заваливать лучше уж дописывать в один файл(append в помощь).
Делать все вручную согласитесь не очень то приятное занятие (и как раньше ученые обходились только карандашем и бумагой )))
Писать целую программу тоже не хочется,по двум причинам первая это лень а вторая как же вы тогда научитесь думать и решать?
если все за вас сделаю я :) Это не интересно и к тому же вредно )))
Итак продолжим "Если величина смещения кратна длине ключа,то совпадет свыше 6 процентов байтов"
следовательно нужно написать фу-ию или процедуру ( хватит уже отдельные программы писать пора писать одну цельную )))
по подсчетам одинаковых байтов и получить процентное отношение.
Логика проста если больше либо равно 6% то переходим к пункту 2.
Можно конечно написать в фу-ии перебор всех возможных длин текста но если подумать здраво то зачем нам пароль длинной с сам текст
или даже половина его это не разумно возьмем к примеру 20 символов длину ключа от 3х до 20ти думаю это стоит учесть в будущей фу-ии.
Алгоритм следующий берем строку из шифрованного текста и накладываем на шифротекст получаем ответ вызываем фу-ию подсчета одинаковых символов
если фу-ия возвращает свыше 6% совпадение то пункт 2 иначе продолжаем цикл до конца текста.
Это домашним заданием будет для вас.
Минимальное смещение я думаю вы уже догадались как можно будет считать ну а 2ой пункт тем более понятен.
Желаю удачи и побольше эксперементируйте не доверяйте теории лучше ее проверяйте, сомневайтесь во всем, истина только в практических результатах.
Итак приступим компилируем наш "кодировщик" Crypt запускаем и вводим любой текст для шифрования,я взял к примеру фразу "Our world is abstraction" и ключ key=26 вот что у нас выходит:
}C@ EY@ZV [E WPEFDSUF_]X
Откроем файл result.txt где сохранили шифротекст и будем думать как его взломать,а долго не будем думать а лучше прочитаем
"Прикладную криптографию" Брюса Шнайера.
Не буду выдумывать и перефразировывать Брюса Шнайера а просто его процитирую:
"Предположим,что открытый текст использует английский язык.Более того,пусть длина ключа любое небольшое число байт.Ниже описано,как взломать этот шифр:
1.Определим длину ключа с помощью процедуры,известной как ПОДСЧЕТ СОВПАДЕНИЙ.
Применим операцию XOR к шифротексту,используя в качестве ключа сам шифротекст с различными смещениями,и подсчитаем совпадающие байты. Если величина смещения кратна длине ключа,то совпадет свыше 6 процентов байтов. Если нет,то будут совпадать меньше чем 0.4 процента( считая,что обычный ASCII текст кодируется случайным ключом,для других типов открытых текстов числа будут другими). Это называется показателем совпадений. Минимальное смещение от одного значения,кратного длине ключа,к другому и есть длина ключа.
2. Сместим шифротекст на эту длину и проведем операцию XOR для смещенного и оригинального шифротекстов.Результатом операции будет удаление ключа и получение открытого текста,подвергнутого операции XOR с самим собой,смещенным на длину ключа. Так как в английском языке на один байт приходится 1.3 бита действительной информации,существующая значительная избыточность позволяет определить способ шифрования."
После многочисленных экспериментов я обнаружил одну маааленькую "неточность" которая делала эксперименты не совсем объективными.
Дело в том что просматривая различные проекты различных авторов находим все возможные модификации шифра цезаря,которые как можно понять
ограничиваются только фантазией и задумкой автора. Возможно я и ошибаюсь но мне кажется что в древней системе шифрования врят ли было допустимо использование
спецвимволов ]{_ + псевдографические символы эпохи ms-dos как в этом шифротексте }C@ EY@ZV [E WPEFDSUF_]X .
Проще говоря захотелось мне использовать только буквы алфавита и ничего более.
Вот к примеру посмотрим на не точность (которая вкралась в программу Crypt) которая искажает стандартный
шифр Цезаря вместо ключа key=3 ключ получается равным 3333333... исправим эту не точность
удалим этот цикл:
for i := 0 to (length(text) div length(key)) do
longkey := longkey + key;
а внутри другого цикла исправим longkey на кey
toto := chr((ord(text[i]) XOR ord(key[i])))
Проверяем и опять получаем туже ситуацию хоть и поменьше,что бы понять в чем "ошибка" посмотрим на таблицу всех символов и их кодов
для этого напишем маленькую программку
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, classes, windows;
var s:tstringlist; st:string; i:integer;
begin
s:=tstringlist.Create; // Создаем список строк
for i:=1 to 1000 do
st:=st+' '+inttostr(i)+'= '+char(ord(i))+#13; // пишем в одну строку код символа = символ+перенос на следующую строку
s.Add(st); // добавляем строку в список
s.SaveToFile('c:\chars.txt'); // сохраняем список в файл
s.Free; // уничтожаем список
winexec(pchar('c:\windows\notepad.exe c:\chars.txt'),sw_show); // что бы вручную не открывать сделаем это автоматически
end.
Желательно прописывать блокнот который поддерживает форматирование,а то выйдет не читабельно.
И вот что мы получаем большие символы английского начинаются с 65 по 90 малые с 97...122 русские с 128...175 и 224...239
Все остальные находящиеся в промежутках нужно вырезать т.е делать обработку после шифрования или что еще лучше внести в код
поправку которая будет не принимать лишний мусор.
На практике запускаем Crypt берем строчку из шифра и применяем ее в качестве пароля к целому шифротексту смотрим на результат
небольшая поправочка что бы программа не затерла шифротекст внесем еще изменения (либо просто переименуйте файл result.txt)
удалим вот эти строки из кода они нам уже не понадобятся
if c in ['Y','y'] then begin
AssignFile(F,'result.txt');
Rewrite(F);
Напишим новые
if fileexists(f) then renamefile(oldname,oldname);
Можно придумать любую модификацию имени,добавлять к имени result порядковый номер
или время ну или конечно свой вариант какой прийдет в голову.
Теперь у нас будет масса файлов что тоже не хорошо,винт заваливать лучше уж дописывать в один файл(append в помощь).
Делать все вручную согласитесь не очень то приятное занятие (и как раньше ученые обходились только карандашем и бумагой )))
Писать целую программу тоже не хочется,по двум причинам первая это лень а вторая как же вы тогда научитесь думать и решать?
если все за вас сделаю я :) Это не интересно и к тому же вредно )))
Итак продолжим "Если величина смещения кратна длине ключа,то совпадет свыше 6 процентов байтов"
следовательно нужно написать фу-ию или процедуру ( хватит уже отдельные программы писать пора писать одну цельную )))
по подсчетам одинаковых байтов и получить процентное отношение.
Логика проста если больше либо равно 6% то переходим к пункту 2.
Можно конечно написать в фу-ии перебор всех возможных длин текста но если подумать здраво то зачем нам пароль длинной с сам текст
или даже половина его это не разумно возьмем к примеру 20 символов длину ключа от 3х до 20ти думаю это стоит учесть в будущей фу-ии.
Алгоритм следующий берем строку из шифрованного текста и накладываем на шифротекст получаем ответ вызываем фу-ию подсчета одинаковых символов
если фу-ия возвращает свыше 6% совпадение то пункт 2 иначе продолжаем цикл до конца текста.
Это домашним заданием будет для вас.
Минимальное смещение я думаю вы уже догадались как можно будет считать ну а 2ой пункт тем более понятен.
Желаю удачи и побольше эксперементируйте не доверяйте теории лучше ее проверяйте, сомневайтесь во всем, истина только в практических результатах.
Комментариев нет:
Отправить комментарий