Главная » Статьи » Delphi » Статьи Delphi

Скачивать материалы с сайта, могут только зарегистрированные пользователи.
Для регистрации заполните два поля ниже!

Через минуту Вы получите "Гостевой доступ"




Модуль для RC5 шифрования
Модуль для RC5 шифрования

Прежде всего немного о самом алгоритме: алгоритм был разработан Рональдом Ривестом (Ronald L. Rivest) для компании RSA Data Security. На основе RC5 в свое время был создан алгоритм шифрования RC6, который участвовал в конкурсе на звание AES (Advanced Encryption Standard - "Продвинутый" алгоритм шифрования). объявленном национальным институтом стандартизации и технологий для замены уже устаревшего алгоритма DES. Тогда RC6 не выиграл только из-за низкой производительности аппаратных реализаций алгоритма. А программные реализации RC5 и RC6 являются, пожалуй, самыми быстрыми среди всех алгоритмов шифрования, обеспечивающих достаточную стойкость перед атаками.

 Например, по некоторым данным скорость грамотно построенной аппаратной реализации алгоритма RC5 на компьютере с скоростью процессора 200 МГц может достигать 10..11 Мбайт/сек, а алгоритма RC6 - 11..12 Мбайт/сек. Для сравнения - скорость работы алгоритма Rijndael (победитель конкурса на звание AES) при вышеозначенных характеристиках процессора может достигать максимум 7 Мбайт/сек.

 Если вам срочно нужно внедрить алгоритмы шифрования в свои коммерческие проекты - на мой взгляд лучший выбор это RC5 или RC6. И не только потому, что они значительно проще в реализации, чем, например, IDEA, но и потому, что RC5 и RC6 (насколько я знаю - ручаться не могу) свободные алгоритмы и вы не должны отчислять часть прибыли при коммерческом использовании алгоритма.

 Итак, RC5 работает с блоками по восемь байт - два 32 битных слова. В отличии от IDEA и Rijndael в RC5 после развертывания ключа вычисляется один подключ, который используется и при шифровании, и при дешифровании. RC5, как и большинство алгоритмов - раундовый алгоритм, другими словами, при шифрации блока над ним производятся одни и те же операции несколько раз, в RC5 таких раундов 12.

 Вот пожалуй и все, что вам нужно знать о теории алгоритма RC5, все остальное видно из модуля. Модуль RC5 похож на модуль IDEA из моей предыдущей статьи. Если вы уже используете модуль IDEA в своих программах - для использования RC5 вам достаточно просто уброть из uses модуль IDEA и включить туда модуль RC5 (все имена методов сохраняются).

{ *********************************************************************** }
{ }
{ Delphi Еncryption Library }
{ Еncryption / Decryption stream - RC5 }
{ }
{ Copyright (c) 2004 by Matveev Igor Vladimirovich }
{ With offers and wishes write: teap_leap@mail.ru }
{ }
{ *********************************************************************** }


unit RC5;

interface

uses
SysUtils, Classes;

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

const
Rounds = 12;
BlockSize = 8;
BufferSize = 2048;
KeySize = 64;
KeyLength = 2 * (Rounds + 1);

P32 = $b7e15163;
Q32 = $9e3779b9;

var
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

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

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;

// Now shorten the key down to one KeySize block by combining the bytes
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);

// Now initialize the S table
S[0] := P32;
for i := 1 to KeyLength-1 do
S[i] := S[i-1] + Q32;

// Now scramble the S table with the key
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+}


end.

 Вот и все что касается RC5 шифрования, в следующей статье мы рассмотрим алгоритм RC6 - заранее могу сказать, что он очень похож на RC5.

 Перепечатка данной статьи разрешается автором только без изменения, модуль, представленный в данной статье абсолютно свободен для использования - пользуйтесь!

Матвеев Игорь Владимирович


Категория: Статьи Delphi | Добавил: c1 (2009 Июль 10)
Просмотров: 813 | Теги: Модуль для RC5 шифрования | Рейтинг: 0.0/0

Выразить благодарность - Поделиться с друзьями!

 

Здесь все о технической стороне 1С!

 

Узнай, как правильно администрировать 1С Предприятие
Регистрируйся на бесплатный 7-ми дневный курс сейчас:

Ваш E-Mail в безопасности



Всего комментариев: 0
avatar