Смекни!
smekni.com

Програмна реалізація криптографічного алгоритму RC5 (стр. 2 из 3)

Активне проникнення в СОД може здійснюватися скритно, тобто в обхід контрольних програм забезпечення збереження інформації.

Найбільш характерні прийоми проникнення: використання точок входу, встановлених в системі програмістами, обслуговуючим персоналом, або точок, виявлених при перевірці ланцюгів системного контролю; підключення до мережі зв'язку спеціального терміналу, що забезпечує вхід в систему шляхом перетину лінії зв'язку законного користувача з ЕОМ з подальшим відновленням зв'язку за типом помилкового повідомлення, а також в мить, коли законний користувач не проявляє активності, але продовжує займати канал зв'язку; анулювання сигналу користувача про завершення роботи з системою і подальше продовження роботи від його імені.

За допомогою цих прийомів порушник, підміняючи на час його законного користувача, може використовувати тільки доступні цьому користувачеві файли; неавторизована модифікація - неавторизований користувач вносить зміни до інформації в файлах, що зберігаються в системі. В результаті користувач, якому ця інформація належить, не може дістати до неї доступ.

Поняття "неавторизований" означає, що перераховані дії виконуються всупереч вказівкам користувача, відповідального за зберігання інформації, або навіть в обхід обмежень, що накладаються на режим доступу в цій системі. Подібні спроби проникнення можуть бути викликані не тільки простим задоволенням цікавості грамотного програміста (користувача), але і навмисним отриманням інформації обмеженого використання.

Можливі і інші види порушень, що приводять до втрати або просочування інформації. Так, електромагнітні випромінювання при роботі ЕОМ і інших технічних засобів СОД можуть бути перехоплені, декодовані і представлені у вигляді бітів, що складають потік інформації.

Тому потрібний рівень захисту від порушника не нижче 3-го класу захисту.

4. Клас засобів КЗІ

Розглянутий комплекс захисту інформації можна віднести до комплексу не нижче 3 класу захищеності систем, що визначений шляхом співставлення:

- цілей безпеки з функціональних послуг безпеки НК;

- функцій сервісів безпеки об’єкту експертизи (ОЕ) з функціональними послугами безпеки НК.

Для співставлення з функціональним програмним забезпеченням функціонального профілю захищеності (ФПЗ) об’єкту експертизи (ОЕ) у якості базового профілю визначено стандартний ФПЗ 2.КЦД.2а, який згідно НД ТЗІ 2.5-008-2002[12] встановлює мінімально необхідний перелік функціональних послуг безпеки та рівнів їх реалізації у комплексах засобів захисту інформації в системах класу безпеки 2 при обробці конфіденційної інформації під час застосування технології, що вимагає підвищених вимог до забезпечення конфіденційності, цілісності та доступності оброблюваної інформації.

5. Блок-схема алгоритму функціонування прикладної програми криптозахисту

Блок-схема алгоритму функціонування прикладної програми криптозахисту наведена на рис.1, 2, 3, 4 і 5.


Рис.1. Загальний алгоритм

Рис.2. Алгоритм процедури EncriptCopy


Рис.3. Алгоритм процедури DecriptCopy

Рис.4. Алгоритм процедури EncriptStream


Рис.4. Алгоритм процедури DecriptStream

6. Листінг тесту програми

unit RC5;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TRC5Block = array[1..2] of LongWord;

TForm1 = class(TForm)

Edit1: TEdit;

Edit2: TEdit;

StaticText1: TStaticText;

StaticText2: TStaticText;

Button1: TButton;

Button2: TButton;

Button3: TButton;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

procedure Button3Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

const

Rounds = 12;

BlockSize = 8;

BufferSize = 2048;

KeySize = 64;

KeyLength = 2 * (Rounds + 1);

P32 = $b7e15163;

Q32 = $9e3779b9;

var

Form1: TForm1;

Key : string;

KeyPtr : PChar;

S : array[0..KeyLength-1] of LongWord;

///////////////////////////////////////////////////////////////////////////////

Додаткові функції

procedure Initialize(AKey: string); // Інійіалізація

procedure CalculateSubKeys; // Підготовлення підключей

function EncipherBlock(var Block): Boolean; // Шифрування блока (8 байт)

function DecipherBlock(var Block): Boolean; // Дешифрування блока

///////////////////////////////////////////////////////////////////////////////

Головні функції

function EncryptCopy(DestStream, SourseStream : TStream; Count: Int64;

Key : string): Boolean; // Зашифрувати дані з одного потоку в іншій

function DecryptCopy(DestStream, SourseStream : TStream; Count: Int64;

Key : string): Boolean; // Розшифрувати дані з одного потоку в іншій

function EncryptStream(DataStream: TStream; Count: Int64;

Key: string): Boolean; // Зашифрувати вміст потоку

function DecryptStream(DataStream: TStream; Count: Int64;

Key: string): Boolean; // Розшифрувати вміст потоку

implementation

{$R *.dfm}

////////////////////////////////////////////////////////////////////////////////

function ROL(a, s: LongWord): LongWord;

asm

mov ecx, s

rol eax, cl

end;

////////////////////////////////////////////////////////////////////////////////

function ROR(a, s: LongWord): LongWord;

asm

mov ecx, s

ror eax, cl

end;

////////////////////////////////////////////////////////////////////////////////

procedure InvolveKey;

var

TempKey : string;

i, j : Integer;

K1, K2 : LongWord;

begin

// Розгортання ключа до довжини 64 символи

TempKey := Key;

i := 1;

while ((Length(TempKey) mod KeySize) <> 0) do

begin

TempKey := TempKey + TempKey[i];

Inc(i);

end;

// Зараз скоротіть ключ знизу до одного KeySize блоку об'єднуючи байти

i := 1;

j := 0;

while (i < Length(TempKey)) do

begin

Move((KeyPtr+j)^, K1, 4);

Move(TempKey[i], K2, 4);

K1 := ROL(K1, K2) xor K2;

Move(K1, (KeyPtr+j)^, 4);

j := (j + 4) mod KeySize;

Inc(i, 4);

end;

end;

////////////////////////////////////////////////////////////////////////////////

procedure Initialize(AKey: string);

begin

Key := AKey;

GetMem(KeyPtr, KeySize);

FillChar(KeyPtr^, KeySize, #0);

InvolveKey;

end;

////////////////////////////////////////////////////////////////////////////////

{$R-,Q-}

procedure CalculateSubKeys;

var

i, j, k : Integer;

L : array[0..15] of LongWord;

A, B : LongWord;

begin

// Copy the key into L

Move(KeyPtr^, L, KeySize);

// Зараз ініціалізуйте S

S[0] := P32;

for i := 1 to KeyLength-1 do

S[i] := S[i-1] + Q32;

// Зараз видирається таблиця S з ключем

i := 0;

j := 0;

A := 0;

B := 0;

for k := 1 to 3*KeyLength do

begin

A := ROL((S[i] + A + B), 3);

S[i] := A;

B := ROL((L[j] + A + B), (A + B));

L[j] := B;

i := (i + 1) mod KeyLength;

j := (j + 1) mod 16;

end;

end;

////////////////////////////////////////////////////////////////////////////////

function EncipherBlock(var Block): Boolean;

var

RC5Block : TRC5Block absolute Block;

i : Integer;

begin

Inc(RC5Block[1], S[0]);

Inc(RC5Block[2], S[1]);

for i := 1 to Rounds do

begin

RC5Block[1] := ROL((RC5Block[1] xor RC5Block[2]), RC5Block[2]) + S[2*i];

RC5Block[2] := ROL((RC5Block[2] xor RC5Block[1]), RC5Block[1]) + S[2*i+1];

end;

Result := TRUE;

end;

////////////////////////////////////////////////////////////////////////////////

function DecipherBlock(var Block): Boolean;

var

RC5Block : TRC5Block absolute Block;

i : Integer;

begin

for i := Rounds downto 1 do

begin

RC5Block[2] := ROR((RC5Block[2]-S[2*i+1]), RC5Block[1]) xor RC5Block[1];

RC5Block[1] := ROR((RC5Block[1]-S[2*i]), RC5Block[2]) xor RC5Block[2];

end;

Dec(RC5Block[2], S[1]);

Dec(RC5Block[1], S[0]);

Result := TRUE;

end;

////////////////////////////////////////////////////////////////////////////////

// Реалізація головних функції

function EncryptCopy(DestStream, SourseStream : TStream; Count: Int64;

Key : string): Boolean;

var

Buffer : TRC5Block;

PrCount : Int64;

AddCount : Byte;

begin

Result := True;

try

if Key = '' then

begin

DestStream.CopyFrom(SourseStream, Count);

Exit;

end;

Initialize(Key);

CalculateSubKeys;

PrCount := 0;

while Count - PrCount >= 8 do

begin

SourseStream.Read(Buffer, BlockSize);

EncipherBlock(Buffer);

DestStream.Write(Buffer, BlockSize);

Inc(PrCount, 8);

end;

AddCount := Count - PrCount;

if Count - PrCount <> 0 then

begin

SourseStream.Read(Buffer, AddCount);

DestStream.Write(Buffer, AddCount);

end;

except

Result := False;

end;

end;

////////////////////////////////////////////////////////////////////////////////

function DecryptCopy(DestStream, SourseStream : TStream; Count: Int64;

Key : string): Boolean;

var

Buffer : TRC5Block;

PrCount : Int64;

AddCount : Byte;

begin

Result := True;

try

if Key = '' then

begin

DestStream.CopyFrom(SourseStream, Count);

Exit;

end;

Initialize(Key);

CalculateSubKeys;

PrCount := 0;

while Count - PrCount >= 8 do

begin

SourseStream.Read(Buffer, BlockSize);

DecipherBlock(Buffer);

DestStream.Write(Buffer, BlockSize);

Inc(PrCount, 8);

end;

AddCount := Count - PrCount;

if Count - PrCount <> 0 then

begin

SourseStream.Read(Buffer, AddCount);

DestStream.Write(Buffer, AddCount);

end;

except

Result := False;

end;

end;

////////////////////////////////////////////////////////////////////////////////

function EncryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean;

var

Buffer : TRC5Block;

PrCount : Int64;

begin

Result := True;

try

if Key = '' then

begin

DataStream.Seek(Count, soFromCurrent);

Exit;

end;

Initialize(Key);

CalculateSubKeys;

PrCount := 0;

while Count - PrCount >= 8 do

begin

DataStream.Read(Buffer, BlockSize);

EncipherBlock(Buffer);

DataStream.Seek(-BlockSize, soFromCurrent);

DataStream.Write(Buffer, BlockSize);

Inc(PrCount, 8);

end;

except

Result := False;

end;

end;

////////////////////////////////////////////////////////////////////////////////

function DecryptStream(DataStream: TStream; Count: Int64; Key: string): Boolean;

var

Buffer : TRC5Block;

PrCount : Int64;

begin

Result := True;

try

if Key = '' then

begin

DataStream.Seek(Count, soFromCurrent);

Exit;

end;

Initialize(Key);

CalculateSubKeys;

PrCount := 0;

while Count - PrCount >= 8 do

begin

DataStream.Read(Buffer, BlockSize);

DecipherBlock(Buffer);

DataStream.Seek(-BlockSize, soFromCurrent);

DataStream.Write(Buffer, BlockSize);

Inc(PrCount, 8);

end;

except

Result := False;

end;

end;

// Завершення головних функції ...

////////////////////////////////////////////////////////////////////////////////

{$R+,Q+}

procedure TForm1.Button1Click(Sender: TObject);

var

SourseStream : TFileStream;

begin

SourseStream := TFileStream.Create(Edit1.Text, fmOpenReadWrite);

EncryptStream(SourseStream, SourseStream.Size, Edit2.Text);

SourseStream.Free;

end;

procedure TForm1.Button2Click(Sender: TObject);

var

SourseStream : TFileStream;

begin

SourseStream := TFileStream.Create(Edit1.Text, fmOpenReadWrite);

DecryptStream(SourseStream, SourseStream.Size, Edit2.Text);

SourseStream.Free;

end;

procedure TForm1.Button3Click(Sender: TObject);

begin

Close

end;

end.

7. Інструкція зі користування програмою

Нижченаведений інтерфейс програми-шифрувальника, що створений засобами Delphi організовує шифрування / дешифрування файлу (рис.6) з використанням функцій EncryptStream / DecryptStream ():

Рис.6. Вікно програми-шифрувальника

До поля „Файл-Джерело” вводиться шлях до файлу з розширенням *.txt чи *.doc, що необхідно зашифрувати, наприклад, C:&bsol;instLog.txt, а до поля „Ключ” вводиться ключ шифрування, наприклад, 135 (рис.7).