- •Минобрнауки россии
- •Кафедра комплексной защиты информационных систем курсовая работа
- •Введение
- •1. Теоретико-математические основы симметричных криптосистем
- •1. 1 Общие понятия симметричных шифров
- •1. 2 Преимущества и недостатки симметричных криптосистем
- •1.3 Блочные шифры
- •2. Алгоритм шифрования blowfish
- •2. 1 Описание алгоритма Blowfish
- •2.2 Процедура расширения ключа
- •2.3 Скорость работы и криптостойкость алгоритма Blowfish
- •3 Практическая реализация алгоритма blowfish
- •3.1 Блок-схема алгоритма шифрования/расшифрования
- •3. 2 Листинг программы
- •3. 3 Интерфейс программы и результаты ее работы
- •Заключение
- •Библиографическийсписок
3 Практическая реализация алгоритма blowfish
3.1 Блок-схема алгоритма шифрования/расшифрования
procedure TForm1.Button1Click (Sender: TObject)
Описание переменных
Имя |
Тип |
Локальная/глобальная |
Описание |
i |
integer |
локальная |
Счётчик цикла |
str_key |
string |
локальная |
Ключ |
str_data |
string |
локальная |
Шифруемый текст |
Data |
array of byte |
глобальная |
Массив блоков шифруемого текста |
Key |
array of byte |
глобальная |
Массив блоков ключа |
IV |
array of byte |
глобальная |
Массив добавочных векторов |
KeyData |
TBlowfishData |
глобальная |
Объект, результат xor |
key_len |
integer |
глобальная |
Длина ключа |
data_len |
integer |
глобальная |
Длина шифруемого текста |
procedure TForm1.Button2Click (Sender: TObject)
Описание переменных
Имя |
Тип |
Локальная/глобальная |
Описание |
i |
integer |
локальная |
Счётчик цикла |
str_key |
string |
локальная |
Ключ |
str_data |
string |
локальная |
Шифруемый текст |
Data |
array of byte |
глобальная |
Массив блоков шифруемого текста |
Key |
array of byte |
глобальная |
Массив блоков ключа |
IV |
array of byte |
глобальная |
Массив добавочных векторов |
KeyData |
TBlowfishData |
глобальная |
Объект, результат xor |
key_len |
integer |
глобальная |
Длина ключа |
data_len |
integer |
глобальная |
Длина шифруемого текста |
3. 2 Листинг программы
unit UMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Blowfish;
type
TForm1 = class(TForm)
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Memo2: TMemo;
Label3: TLabel;
Memo3: TMemo;
Button1: TButton;
Label4: TLabel;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Data: array of byte;
Key: array of byte;
IV: array of byte;
KeyData: TBlowfishData;
key_len, data_len:integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); //кодирование
var
i: integer;
str_key:string;
str_data:string;
begin
str_key:=Edit1.Text;
str_data:=Memo1.Lines.Text;
data_len:=Length(str_data);
Setlength (Data,data_len);
for i:=0 to data_len-1 do Data[i]:=ord(str_data[i+1]);
key_len:=Length(str_key);
Setlength (Key,key_len);
for i:=0 to key_len-1 do Key[i]:=ord(str_key[i+1]);
Setlength (IV,key_len);
for i:=0 to key_len-1 do IV[i]:=random(256);
BlowfishInit(KeyData,@Key,Sizeof(Key),@IV);
for i:= 1 to (data_len div 8) do
BlowfishEncrypt(KeyData,@Data[(i-1)*8],@Data[(i-1)*8]);
for i:=1 to data_len do str_data[i]:=chr(Data[i-1]);
Memo2.Lines.Text:=str_data;
BlowfishReset(KeyData);
Button2.Enabled:=true;
end;
procedure TForm1.Button2Click(Sender: TObject); //расскодирование
var
i: integer;
str_key:string;
str_data:string;
begin
for i:= 1 to (data_len div 8) do
BlowfishDecrypt(KeyData,@Data[(i-1)*8],@Data[(i-1)*8]);
str_data:='';
for i:=0 to data_len-1 do str_data := str_data + chr(Data[i]);
Memo3.Lines.Text:=str_data;
BlowfishReset(KeyData);
BlowfishBurn(KeyData);
end;
end.
{
64 bit блок шифрования
Длина ключа - до 448 bit
}
unit Blowfish;
interface
uses
Sysutils, Tools;
type
TBlowfishData= record
InitBlock: array[0..7] of byte; { инициализация вектора }
LastBlock: array[0..7] of byte; { значение вектора }
SBoxM: array[0..3,0..255] of DWord;
PBoxM: array[0..17] of DWord;
end;
procedure BlowfishInit(var Data: TBlowfishData; Key: pointer; Len: integer; IV: pointer);
{ initializes the TBlowfishData structure with the key information and IV if applicable }
procedure BlowfishBurn(var Data: TBlowfishData);
{ удаление информации о ключе }
procedure BlowfishEncrypt(var Data: TBlowfishData; InData, OutData: pointer);
{ кодирование при длине блока в 64 бита }
procedure BlowfishDecrypt(var Data: TBlowfishData; InData, OutData: pointer);
{ раскодирование при длине блока в 64 бита }
procedure BlowfishReset(var Data: TBlowfishData);
{ очистка информации }
{******************************************************************************}
implementation
{$I Blowfish.inc}
{$R-}
procedure BlowfishInit;
var
i, k: integer;
A: DWord;
KeyB: PByteArray;
Block: array[0..7] of byte;
begin
if (Len<= 0) or (Len> 56) then
raise Exception.Create('Ключ должен быть длинной от 1 до 56 байт');
KeyB:= Key;
Move(SBox,Data.SBoxM,Sizeof(SBox));
Move(PBox,Data.PBoxM,Sizeof(PBox));
with Data do
begin
if IV= nil then begin
FillChar(InitBlock,8,0);
FillChar(LastBlock,8,0);
end
else
begin
Move(IV^,InitBlock,8);
Move(IV^,LastBlock,8);
end;
k:= 0;
for i:= 0 to 17 do begin
A:= KeyB[(k+3) mod Len];
A:= A + (KeyB[(k+2) mod Len] shl 8);
A:= A + (KeyB[(k+1) mod Len] shl 16);
A:= A + (KeyB[k] shl 24);
PBoxM[i]:= PBoxM[i] xor A;
k:= (k+4) mod Len;
end;
FillChar(Block,Sizeof(Block),0);
for i:= 0 to 8 do begin
BlowfishEncrypt(Data,@Block,@Block);
PBoxM[i*2]:= Block[3] + (Block[2] shl 8) + (Block[1] shl 16) + (Block[0] shl 24);
PBoxM[i*2+1]:= Block[7] + (Block[6] shl 8) + (Block[5] shl 16) + (Block[4] shl 24);
end;
for k:= 0 to 3 do begin
for i:= 0 to 127 do begin
BlowfishEncrypt(Data,@Block,@Block);
SBoxM[k,i*2]:= Block[3] + (Block[2] shl 8) + (Block[1] shl 16) + (Block[0] shl 24);
SBoxM[k,i*2+1]:= Block[7] + (Block[6] shl 8) + (Block[5] shl 16) + (Block[4] shl 24);
end;
end;
end;
end;
procedure BlowfishBurn(var Data: TBlowfishData);
begin
FillChar(Data,Sizeof(Data),0);
end;
function BF_F(Data: TBlowfishData; xL: DWord): DWord;
begin
Result:= (((Data.SBoxM[0,(xL shr 24) and $FF] + Data.SBoxM[1,(xL shr 16) and $FF]) xor Data.SBoxM[2,(xL shr 8) and $FF]) + Data.SBoxM[3,xL and $FF]);
end;
procedure BFDoRound(Data: TBlowfishData; var xL, xR: DWord; RNum: integer);
begin
xL:= xL xor BF_F(Data,xR) xor Data.PBoxM[RNum];
end;
procedure BlowfishEncrypt;
var
xL, xR: DWord;
begin
Move(InData^,xL,4);
Move(pointer(integer(InData)+4)^,xR,4);
xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
xL:= xL xor Data.PBoxM[0];
BFDoRound(Data,xR,xL,1);
BFDoRound(Data,xL,xR,2);
BFDoRound(Data,xR,xL,3);
BFDoRound(Data,xL,xR,4);
BFDoRound(Data,xR,xL,5);
BFDoRound(Data,xL,xR,6);
BFDoRound(Data,xR,xL,7);
BFDoRound(Data,xL,xR,8);
BFDoRound(Data,xR,xL,9);
BFDoRound(Data,xL,xR,10);
BFDoRound(Data,xR,xL,11);
BFDoRound(Data,xL,xR,12);
BFDoRound(Data,xR,xL,13);
BFDoRound(Data,xL,xR,14);
BFDoRound(Data,xR,xL,15);
BFDoRound(Data,xL,xR,16);
xR:= xR xor Data.PBoxM[17];
xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
Move(xR,OutData^,4);
Move(xL,pointer(integer(OutData)+4)^,4);
end;
procedure BlowfishDecrypt;
var
xL, xR: DWord;
begin
Move(InData^,xL,4);
Move(pointer(integer(InData)+4)^,xR,4);
xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
xL:= xL xor Data.PBoxM[17];
BFDoRound(Data,xR,xL,16);
BFDoRound(Data,xL,xR,15);
BFDoRound(Data,xR,xL,14);
BFDoRound(Data,xL,xR,13);
BFDoRound(Data,xR,xL,12);
BFDoRound(Data,xL,xR,11);
BFDoRound(Data,xR,xL,10);
BFDoRound(Data,xL,xR,9);
BFDoRound(Data,xR,xL,8);
BFDoRound(Data,xL,xR,7);
BFDoRound(Data,xR,xL,6);
BFDoRound(Data,xL,xR,5);
BFDoRound(Data,xR,xL,4);
BFDoRound(Data,xL,xR,3);
BFDoRound(Data,xR,xL,2);
BFDoRound(Data,xL,xR,1);
xR:= xR xor Data.PBoxM[0];
xL:= (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR:= (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
Move(xR,OutData^,4);
Move(xL,pointer(integer(OutData)+4)^,4);
end;
procedure BlowfishReset;
begin
Move(Data.InitBlock,Data.LastBlock,8);
end;
end.
unit Tools;
interface
uses
Sysutils;
type
{$IFDEF VER120}
dword= longword;
{$ELSE}
dword= longint;
{$ENDIF}
function LRot16(X: word; c: integer): word; assembler;
function RRot16(X: word; c: integer): word; assembler;
function LRot32(X: dword; c: integer): dword; assembler;
function RRot32(X: dword; c: integer): dword; assembler;
procedure XorBlock(I1, I2, O1: PByteArray; Len: integer);
procedure IncBlock(P: PByteArray; Len: integer);
implementation
function LRot16(X: word; c: integer): word; assembler;
asm
mov ecx,&c
mov ax,&X
rol ax,cl
mov &Result,ax
end;
function RRot16(X: word; c: integer): word; assembler;
asm
mov ecx,&c
mov ax,&X
ror ax,cl
mov &Result,ax
end;
function LRot32(X: dword; c: integer): dword; assembler;
asm
mov ecx,&c
mov eax,&X
rol eax,cl
mov &Result,eax
end;
function RRot32(X: dword; c: integer): dword; assembler;
asm
mov ecx,&c
mov eax,&X
ror eax,cl
mov &Result,eax
end;
procedure XorBlock(I1, I2, O1: PByteArray; Len: integer);
var
i: integer;
begin
for i:= 0 to Len-1 do O1[i]:= I1[i] xor I2[i];
end;
procedure IncBlock(P: PByteArray; Len: integer);
begin
Inc(P[Len-1]);
if (P[Len-1]= 0) and (Len> 1) then IncBlock(P,Len-1);
end;
end.
