Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #65, МАЙ 2004 г.

Шифруйся сам!

Alek Silverstone

Xakep, номер #065, стр. 065-110-3


Циклический сдвиг влево

function ROL(c:Longword;n:byte):Longword;assembler;

asm

mov eax,c

mov cl,n

rol eax,cl

end;

Эта функция сдвигает 32-битовое слово c на n бит влево.

Вторая проблема - константы. Таблицу констант сначала надо заполнить. В t[i] (i от 1 до 64) заносится целая часть от 2^32*|sin(i)|, где i измеряется в радианах:

for i:=1 to 64 do t[i]:=trunc(4294967296*abs(sin(i)));

Собственно операции приведены на врезке. Основной цикл MD5 (я назвал его MD5Do) занимает очень много места, и нет смысла приводить его здесь. Его код вместе с комментариями есть на диске.

Но тут надо сделать одно важное замечание. MD5Do нужно компилить с выключенным Overflow checking (зайти в Project -> Options на вкладку Compiler и снять одноименную галку или в начале кода написать директиву компилятора {$Q-}). Если этого не сделать, то при стандартных настройках после нескольких циклов прога будет вылетать из-за переполнения в последних процедурах inc. И еще, по поводу констант. Вводить их ручками сложно (можно сойти с ума), очень легко ошибиться и очень трудно потом эту ошибку найти. Поэтому я написал небольшую программку, которая подсчитывает эти константы и выводит их (я не подсчитываю их непосредственно перед вызовом хеш-функции из-за соображений скорости). Остается только скопировать их.

Теперь последний штрих. Последняя процедура возвращает значения md5a, md5b, md5c и md5d.

procedure MD5Finalize(var a, b, c, d:Longword);

begin

a:=md5a;

b:=md5b;

c:=md5c;

d:=md5d;

end;

Эта процедура возвращает в параметрах a, b, c, d четыре части результата. По стандарту MD5 возвращает значение, начиная с младшего байта a и заканчивая старшим байтом d, в шестнадцатеричном виде. С этим связана еще одна проблема (последняя на сегодня ;)) - функция IntToHex. Мне так и не удалось понять, как она работает (она на asm'е), могу лишь предположить, что проблема в порядке битов. Факт в том, что у меня вместо, например, "12345678" получалось "78563412". Поэтому пришлось писать вот такой изврат:

Перемены значений

function IntToHexFix(a:LongWord):string;

var b,r:string[8];

begin

b:=IntToHex(a,8);

SetLength(r,8);

r[7]:=b[1];

r[8]:=b[2];

r[5]:=b[3];

r[6]:=b[4];

r[3]:=b[5];

r[4]:=b[6];

r[1]:=b[7];

r[2]:=b[8];

Result:=r;

end;

Тестируем

Теперь напишем небольшую программку для того, чтобы проверить наш код. Сразу оговорюсь, что сейчас мы будем тестировать только RC4 - MD5 потребовал бы слишком много места в журнале. Но не волнуйся, на диске есть все ;). Кинем на форму (Form1) кнопку (назовем ее RC4Btn), поле ввода (KeyEdit) и диалог выбора файла (OpenDialog). В последнем не забудем задать фильтр *.* (свойство Filter). Напишем такой обработчик щелчка по RC4Btn:

Обрабатываем клик

procedure TForm1.RC4BtnClick(Sender: TObject);

var

//файлы для чтения и записи информации

InFile, OutFile :file of byte;

t:byte; //байт для шифрования

begin

if OpenDialog.Execute and (KeyEdit.Text<>'') and (OpenDialog.Filename<>'') then begin

// если файл выбран и ключ введен, то...

Назад на стр. 065-110-2  Содержание  Вперед на стр. 065-110-4