Как сделать программу шифрования


Member

 

Сообщений: 71

Сказал(а) спасибо: 0

Поблагодарили 3 раз(а) в 3 сообщениях

Регистрация: 04.03.2008

По умолчанию 25.11.2009, 18:17
Обнаружился еще один интересный линк: статья самого автора алгоритма
с примером на Туробо-Паскале:
http://reference.kfupm.edu.sa/content/k/b/...g_al_119066.pdf
С этой точки зрения программа на ассемблере представляет такой интерес:
на самом деле эта программа и _была_ изначально написана на ассемблере (а вот где
её теперь найти... если сам James Massey это от нас скрыл...)
И последующие переписывания на Паскаль и Си окончательно сбили с толку.
Большой интерес представлят тот факт, что сам код шифрации - дешифрации
вообще не содержит ассемблерных команд (!) а состоит из макрокоманд, которые
могут быть адаптированы практически под любой существующий процессор,
(за исключением может быть барахла типа PIC-Microchip)
Идея такая. Существуют взаимно обратные операции над байтами.
Сложение - вычитание (ADD SUB) Их многие знают. Для любых чисел y+x-x=y.
XOR - XOR. (y xor x) xor x=y
Перестановка бит - Перестановка бит и ее частные случаи:
Цикл. сдвиг вправо - влево (ROR ROL)
Перестановка байт.
Есть еще одна очень хорошая взаимно-обратная пара: подстановка байт по таблице.
Т е в первой таблице мы пишем что-то вроде А -> И У -> Ж, а во второй
И -> А, Ж -> У. В данном случае в 256 байтной таблице должны находиться байты от 0 до
255 в произвольном псевдослучайном порядке, а 2я таблица должна быть обратной к первой.
Естественно, что можно создать порядка 256! (факториал) таких таблиц, какие из
них будут "очень случайные" - это вопрос, но подходящих таблиц много.
Как ставится задача. Есть 8 байт (64 бита) данных. Необходимо так обработать эти биты,
чтобы они не только псевдослучайно изменились с 0 на 1 и обратно, но и псевдослучайно
поменялись бы местами в пределах всех 64 бит. Понятно, что если мы будем применять
операции типа ADD и XOR над байтом, то это никак не повлияет на другие байты.
Для того, чтобы обеспечить "более надежную" шифрацию, James Massey предлагает
операцию над двумя байтами (big smile) вида
{ y = y + x; x = x + y; } и обратная { x = x - y; y = y - x; }
и эту операцию почему-то называет Трансформацией Псевдо Хадамара (PHT)
(за что бедного Адамара обозвали ПсевдоХадамаром?)
Кроме как сделать программу шифрования того, даже такой подход не обеспечивает надежного (по мнению Massey) шифрования.
И тут в дело идут таблицы подстановки, которые маскируют недостатки элементарных операций,
а элементарные операции маскируют недостатки таблиц подстановки. И естественно,
сменив пару таблиц мы полностью меняем результат шифрования, что позволяет практически
моментально создавать разные версии шифра.
Вторым элементом алгоритма является растягивание ключа пользователя (назовем его simplekey)
до фиксированного размера (2rounds+1)8 байт, где rounds - число циклов шифрования.
Назовем растянутый ключ extkey. Massey подчеркивает, что extkey должен генериться
всегда так, чтобы не иметь повторяющихся байт. Генерация extkey фактически независима
от алгоритма шифрации (и может быть разной), но мы возьмем тот способ, который описан в pdf.
Итак программа строится следующим образом:
1) Генерация взаимно-обратных таблиц подстановки.
2) Расширение ключа до (2rounds+1)8 байт.
3a) Шифрование, причем ключ extkey читается от начала до конца.
3b) Либо расшифровка, причем в полностью обратном порядке проделываются обратные операции,
а ключ при этом читается от конца до начала.
За основу процедуры расширения ключа всята программа Massey из PDF, а за основу других
процедур - ранее упомянутая C программа с греческого сайта.
Использовался ассемблер masm 5.10 Microsoft, 1988 и линкер Link 3.64 Microsoft, 1988
Файл компиляции m.bat
masm safer.asm,,safer.lst;
link safer.obj;
safer.exe
Файл демо-версии SAFER K-64:

Код:

.model small stdout=0; файл вывода (дисплей) rounds=5; число циклов шифрования cseg segment ; все сегментные регистры будут указывать на 1 сегмент assume cs:cseg,ds:cseg,es:cseg ; вывод строки текста на экран prn macro txt local m1,m2 jmp m2 m1 db txt db 13,10 m2: mov bx,stdout mov dx,offset m1 mov cx,offset m2-offset m1 mov ah,40h int 21h endm ; элементарные операции шифрования ; let dst=src (используется шифрования для перестановки байт) xmov macro dst,src mov AL,src mov dst,AL endm ; элем операции над байтом данных dst и расш ключом extkey, на который указывает SI ; операции en.. предполагают что lodsb увеличивает SI на 1, т е mov AL,[SI] : inc SI ; (cld перед началом цикла шифрования) ; операции de.. предполагают что lodsb уменьшает SI на 1, т е mov AL,[SI] : dec SI ; (std перед началом цикла дешифрования) enadd macro dst lodsb add dst,al endm deadd macro dst lodsb sub dst,al endm enxor macro dst lodsb xor dst,al endm dexor macro dst lodsb xor dst,al endm ; операции для "размывания" бит между байтами ; C declaration ;#define PHT(x, y) { y += x; x += y; } enPHT macro x,y mov AL,x add y,AL mov AL,y add x,AL endm ; C declaration ; IPHT(x, y) { x -= y; y -= x; } dePHT macro x,y mov AL,y sub x,AL mov AL,x sub y,AL endm org 0 start: jmp beg ; шифруемый 8байтовый блок, он же 8 отдельных байтовых переменных buf label byte ra db 48; тестовые данные "01234567" rb db 49 rc db 50 rd db 51 re db 52 rf db 53 rg db 54 rh db 55 ; конец 8 байтового блока db 13,10; CR,LF (используется для вывода результата на экран) rt db 0 ; 12345678 ; ключ шифрования ; для удобства допускается ключ только длиной 8 байт simplekey db "testpass"; введите сюда свой любимый пароль k1table db 8 dup (0) ; расширенный ключ, по которому собственно идет процесс (псевдослучайная последовательность) extkey db (2rounds+1)8 dup (0) ; таблицы подстановки (псевдослучайная последовательность) exptab db 256 dup (0) logtab db 256 dup (0) ; имена тестовых файлов ; требуется, чтобы в каталоге с safer.exe был файл testfile.txt ; программа шифрует его по ключу (см выше), создавая testenco.txt ; затем программа расшифровывает testenco.txt, создавая testdeco.txt fname1 db "testfile.txt",0 fname2 db "testenco.txt",0 fname3 db "testdeco.txt",0 ; дескрипторы файлов fi dw 0 fo dw 0 ; dst=exptab[dst] doexp macro dst mov BX,offset exptab mov AL,dst XLAT mov dst,AL endm ; dst=logtab[dst] dolog macro dst mov BX,offset logtab mov AL,dst XLAT mov dst,AL endm enc0: loop encodloop jmp enc1 ; процедура шифрования encode: cld; LODSB работает "вверх" mov CX,rounds mov SI,offset extkey; SI=начало extkey ; комментариев не будет. Правда просто? ; Трюк состоит в том, что единственная ошибка приводит к тому, что невозможно понять ; где именно она находится "Зашифрованный текст" "расшифруется" обратно абсолютно непонятным образом encodloop: enxor ra; битовые операции enadd rb enadd rc enxor rd enxor re enadd rf enadd rg enxor rh doexp ra; подстановка по таблицам dolog rb dolog rc doexp rd doexp re dolog rf dolog rg doexp rh enadd ra; битовые операции enxor rb enxor rc enadd rd enadd re enxor rf enxor rg enadd rh enPHT ra, rb; "размывание" enPHT rc, rd enPHT re, rf enPHT rg, rh enPHT ra, rc enPHT re, rg enPHT rb, rd enPHT rf, rh enPHT ra, re enPHT rb, rf enPHT rc, rg enPHT rd, rh xmov rt,rb; перестановка байт xmov rb,re xmov re,rc xmov rc,rt xmov rt,rd xmov rd,rf xmov rf,rg xmov rg,rt jmp enc0 ; конец цикла (см выше) enc1: enxor ra; эта группа операций не совсем обоснована теорией enadd rb enadd rc enxor rd enxor re enadd rf enadd rg enxor rh ret dec0: loop decloop jmp dec1 ; процедура дешифрования ; производит обратные операции в строго противоположном порядке decode: std; LODSB работает "вниз" mov CX,rounds mov SI,offset extkey+(2rounds+1)8-1; SI=конец extkey dexor rh deadd rg deadd rf dexor re dexor rd deadd rc deadd rb dexor ra decloop: xmov rt,re xmov re,rb xmov rb,rc xmov rc,rt xmov rt,rf xmov rf,rd xmov rd,rg xmov rg,rt dePHT ra, re dePHT rb, rf dePHT rc, rg dePHT rd, rh dePHT ra, rc dePHT re, rg dePHT rb, rd dePHT rf, rh dePHT ra, rb dePHT rc, rd dePHT re, rf dePHT rg, rh deadd rh dexor rg dexor rf deadd re deadd rd dexor rc dexor rb deadd ra dolog rh doexp rg doexp rf dolog re dolog rd doexp rc doexp rb dolog ra dexor rh deadd rg deadd rf dexor re dexor rd deadd rc deadd rb dexor ra jmp dec0 dec1: cld; строковые операции снова работают "вверх" (как принято делать по умолчанию) ret ; создание взаимно-обратных таблиц подстановки ;; C prototype ;;void _mcrypt_Safer_Init_Module(void) ;;{unsigned int i, exp; ;;exp = 1; ;;for (i = 0; i < TAB_LEN; i++) ;;{exp_tab[i] = (unsigned char) (exp & 0xFF); ;;log_tab[exp_tab[i]] = (unsigned char) i; ;;exp = exp 45 % 257;}} tabinit: mov AX,1; используем AX как переменную exp (см прототип) mov CX,0; используем CX как счетчик цикла i mov SI,offset exptab mov DI,offset logtab ta1: mov BX,CX ; exp_tab[i] = (unsigned char) (exp & 0xFF); mov [SI+BX],AL mov BL,AL ; log_tab[exp_tab[i]] = (unsigned char) i; mov BH,0 mov [DI+BX],CL mov BX,45 ; exp = exp 45 % 257; mul BX; DX:AX=AXBX mov BX,257 div BX; AX=частное, DX=остаток деления mov AX,DX inc CX cmp CX,256 jnz ta1 ret ; расширение 8байтового ключа simplekey до ключа extkey длины (2rounds+1)8 байт ;; Прототип расширения ключа до необходимой длины как он описан в ;; SAFER K-64: A Byte-Oriented Block-Ciphering Algorithm, James L. Massey ;; http://reference.kfupm.edu.sa/conten..._al_119066.pdf ;; (Турбо-Паскаль, фрагмент) ;; writeln('The KEY is ', k[1,1]:8,k[1,2]:4,k[1,3]:4,k[1,4]:4, ;; k[1,5]:4,k[1,6]:4,k[1,7]:4,k[1,8]:4); ;; {The next instructions implement the key schedule needed to derive keys ;; K2, K3,... K2r+1 from the user-selected key K1.} ;; FOR i:= 2 TO 2r + 1 DO ;; FOR j:= 1 TO 8 DO ;; BEGIN ;; {Each byte of the key K1 is further left rotated by 3.} ;; k1[j]:= (k1[j] shl 3) + (k1[j] shr 5); ;; {The key bias is added here.} ;; k[i,j]:= k1[j] + exptab[exptab[9i+j]]; ;; END; expandkey: cld mov si,offset simplekey mov di,offset k1table mov cx,8 rep movsb mov si,offset simplekey mov di,offset extkey mov cx,8 rep movsb mov ch,2; FOR i:= 2 TO 2r + 1 DO ek2: mov SI,offset k1table mov cl,1; FOR j:= 1 TO 8 DO ek1: mov al,[SI]; циклический сдвиг 3 бита влево; k1[j]:= (k1[j] shl 3) + (k1[j] shr 5) rol al,1 rol al,1 rol al,1 mov [SI],al mov al,ch; =9i+j mov ah,9 mul ah add al,cl adc ah,0 doexp AL; =exptab[...] add AL,[SI]; =k1[j]+exptab[...] mov [DI],AL inc SI; следующий байт k1table inc DI; следующий байт extkey inc CL cmp CL,9 jnz ek1 inc CH cmp CH,2rounds+2 jnz ek2 ret ; основная тестовая программа beg: push cs pop ds push cs pop es call tabinit; создать таблицы подстановки call expandkey; расширить ключ call prntestline; напечатать исходные данные call encode ; зашифровать call prntestline; напечатать шифрованные данные call decode ; расшифровать call prntestline; напечатать расшифрованные данные call filedemo ; зашифровать и расшифровать файл exit: mov ax,4C00h; выход в DOS int 21h errexit2: jmp errexit filedemo: ; демо шифрования файла prn "Encoding file..." mov dx,offset fname1; открыть исходный файл для чтения mov ax,3D00h int 21h jc errexit2 mov fi,ax mov cx,0 ; создать новый шифрованный файл mov dx,offset fname2 mov ax,3C00h int 21h jc errexit2 mov fo,ax encfil1:mov al,0 ; перед загрузкой данных буфер заполняется 0, т к длина файла может быть не кратна 8 mov di,offset buf mov cx,8 cld rep stosb mov dx,offset buf ; читать 8 байт mov bx,fi mov cx,8 mov ah,3Fh int 21h cmp ax,0 ; это конец файла? jz encfil2 call encode ; нет, шифровать mov dx,offset buf ; записать результат в файл с дескриптором fo mov bx,fo mov cx,8 mov ah,40h int 21h jmp encfil1 encfil2: call closefiles ; закрыть файлы prn "Decoding file..."; демо расшифровки аналогично mov dx,offset fname2; открыть mov ax,3D00h int 21h jc errexit mov fi,ax mov cx,0 mov dx,offset fname3 mov ax,3C00h int 21h jc errexit mov fo,ax decfil1:mov al,0 ; цикл расшифровки mov di,offset buf mov cx,8 cld rep stosb mov dx,offset buf mov bx,fi mov cx,8 mov ah,3Fh int 21h cmp ax,0 jz decfil2 call decode mov dx,offset buf mov bx,fo mov cx,8 mov ah,40h int 21h jmp decfil1 decfil2: call closefiles ; закрыть файлы prn "Ok!" ret errexit: prn "File opening error?"; ошибка при открытии call closefiles ; возможно нет тестового файла testfile.txt jmp exit closefiles: mov bx,fi mov fi,0 cmp bx,0 jnz cf1 mov ah,3Eh int 21h cf1: mov bx,fo mov fo,0 cmp bx,0 jnz cf2 mov ah,3Eh int 21h cf2: ret ; печать тестовой строки, чтобы видеть: она действительно зашифровывается и расшифровывается prntestline: mov dx,offset buf mov cx,10 ; 8 байт данных и CR,LF mov bx,stdout mov ah,40h int 21h ret cseg ends end start
Для испытаний нужен файл с именем testfile.txt (можно бинарный)
Если вдруг не удастся утянуть программу через COPY-PASTE или скомпилировать, или она не заработает - пишите.
Ответить с цитированием



Рекомендуем посмотреть ещё:


Закрыть ... [X]

Как написать программу для шифрования и дешифрования алгоритма Как сделать массу на кнопку

Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования Как сделать программу шифрования

Похожие новости