уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Рано или поздно разработчику приходится сталкиваться с вопросами защиты информации, обеспечения конфиденциальности и т.д. Мне пришлось столкнуться с этой проблемой сравнительно недавно и, так как я не являюсь специалистом в вопросах криптографии и, тем более, не намереваюсь разрабатывать сверхбыстрый и уникальный компонент для шифрования, то решил выбрать подходящий для меня компонент из уже имеющихся в Сети. Первоначальная задача, которая передо мной была поставлена — обеспечить шифрование файлов с использованием алгоритма AES (Rijndael) перед их отправкой на сервер. И, так как никто меня не ограничивал в выборе компонентов, то я решил начать работу в этой области с компонентов DCPcrypt о которых я рассказывал про расчёт SHA1 в Delphi.

Установка компонентов

  1. Скачиваем архив с компонентами DCPCrypt с официального сайта (я скачивал DCPcrypt v2 for Delphi 2009/2010)
  2. Распаковываем архив в любую папку
  3. Добавляем путь к папке с компонентами и подпапкам Ciphers и Hashes в Tools—>Options—>Library
  4. Далее, выбираем пакет установки DCPdelphi2009.dpk и устанавливаем компоненты.
У меня Delphi 10 и компоненты установились без проблем

dcpcrypt установка

После установки на палитре компонентов появятся две новые вкладки: DCPciphers и DCPhashes. После установки компонентов можно приступать к работе.

Демонстрационный проект

Открываем на палитре компонентов вкладку DCPciphers и бросаем на форму компонент TDCP_rijndael.  Остальные компоненты берем с вкладок Standard и Dialogs. Окно приложения с помощью которого мы будем учиться использовать компоненты DCPCrypt представлено на рисунке ниже:

пример dcpcrypt aes

С помощью такого нехитрого приложения мы сможем посмотреть как работают компоненты, а, заодно, и оценить затраты времени на шифрование файлов различного размера.

Для начала, напишем две функции для шифрования и расшифровки файла. Первая — шифрование файла:

function TForm2.EncryptFile(Source, Dest, Password: string): Boolean;
var
  SourceStream, DestStream: TFileStream;
begin
  Result := True;
  try
    SourceStream := TFileStream.Create(Source, fmOpenRead);//поток для файла, который будем шифровать
    try
      DestStream := TFileStream.Create(Dest, fmCreate);//поток файла для зашифрованных данных
      try
        DCP_rijndael1.InitStr(Password, TDCP_sha1);//инициализируем ключ (считаем SHA1 для ключа)
        DCP_rijndael1.EncryptStream(SourceStream, DestStream, SourceStream.Size);//шифруем
        DCP_rijndael1.Burn;//"сжигаем" данные о ключе
      finally
        FreeAndNil(DestStream);
      end;
    finally
      FreeAndNil(SourceStream)
    end;
  except
    Result := False;
  end;
end;

Аналогичным образом выглядит функция и для расшифровки файла:

function TForm2.DecryptFile(Source, Dest, Password: string): Boolean;
var
  SourceStream, DestStream: TFileStream;
begin
  Result := True;
  try
    SourceStream := TFileStream.Create(Source, fmOpenRead);
    try
      DestStream := TFileStream.Create(Dest, fmCreate);
      try
        DCP_rijndael1.InitStr(Password, TDCP_sha1);
        DCP_rijndael1.DecryptStream(SourceStream, DestStream, SourceStream.Size);
        DCP_rijndael1.Burn;
      finally
        FreeAndNil(DestStream);
      end;
    finally
      FreeAndNil(SourceStream)
    end;
  except
    Result := False;
  end;
end;

Теперь используем эти функции в обработчиках событий OnClick кнопок «Шифровать» и «Расшифровать». Для подсчёта времени, затраченного на проведение операции я воспользовался способом, про который я рассказывал здесь.

//Шифруем файл
procedure TForm2.btnEncryptClick(Sender: TObject);
var
  iCounterPerSec: TLargeInteger;
  T1, T2: TLargeInteger; // значение счётчика ДО и ПОСЛЕ операции
  SourceStream, DestStream: TFileStream;
begin
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(T1);
 
  if EncryptFile(edFile.Text, ExtractFilePath(ParamStr(0)) + 'encrypted' + ExtractFileExt(edFile.Text), edPassword.Text) then
  begin
    QueryPerformanceCounter(T2);
    lbTimer.Caption := FormatFloat('0.0000', (T2 - T1) / iCounterPerSec) + ' сек.';
  end
  else
    lbTimer.Caption := 'Ошибка!'
end;
//Расшифровываем файл
procedure TForm2.btnDecryptClick(Sender: TObject);
var
  iCounterPerSec: TLargeInteger;
  T1, T2: TLargeInteger; // значение счётчика ДО и ПОСЛЕ операции
  SourceStream, DestStream: TFileStream;
begin
  QueryPerformanceFrequency(iCounterPerSec);
  QueryPerformanceCounter(T1);
 
  if DecryptFile(edFile.Text, ExtractFilePath(ParamStr(0)) + 'decrypted' + ExtractFileExt(edFile.Text), edPassword.Text) then
  begin
    QueryPerformanceCounter(T2);
    lbTimer.Caption := FormatFloat('0.0000', (T2 - T1) / iCounterPerSec) + ' сек.';
  end
  else
    lbTimer.Caption := 'Ошибка!'
end;

Теперь проверим работу нашей программы. Для примера, я создал файл с названием «example.txt» и содержащим всего одну строку «Шла Саша по шоссе и сосала чупа-чупс». Запускаем программу, выбираем наш тестовый файл, задаем любой пароль и жмем кнопку «Шифровать». Результат работы программы представлен на рисунке ниже:
result
При этом, зашифрованный файл стал таким:
result_file
Аналогичным образом, если выбрать зашифрованный файл и задать тот же самый ключ, произойдет и обратная операция — расшифровка файла и помещение его содержимого в файл decrypted.

«Безопасность всегда дается ценой производительности»

Конечно, фраза из заголовка относилась не совсем к тому, что я сейчас собираюсь показать, но, тем не менее. Посмотрим, сколько времени затрачивается при использовании DCPCrypt для того, чтобы зашифровать файлы самых различных размеров и с самым различным содержимым.

Размер файла Тип файла Время шифрования, с Время расшифровки, с
1 Кб Текст 0,0052 0,0015
1 Мб DLL 0,0398 0,0729
11 Мб EXE 0,952 0,942
73 Мб EXE 3,5011 3,7917
1490 Мб Фильм 45,5644 33,8211

В принципе, вполне приемлемый результат, учитывая то, что при предыдущей проверке на производительность эти компоненты показали второй по скорости результат, думаю, что вполне подойдут для дальнейшей работы.
Дополнительно отмечу, что одним из преимуществ этих компонентов, лично для себя, я определил — простоту их использования. С их помощью одинаково просто можно шифровать и строки и целые файлы.

Скачать исходник: Исходники —> Прочие
5 3 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
8 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Stalker4
Stalker4
02/06/2016 17:24

Добрый день, Скачал по указанной вами ссылке dcpcrypt2-2010.zip. Установил библиотеку под Delphi 7.1 (DCPdelphi6.dpk) и Delphi 10 Seattle Update1 (DCPdelphi2009.dpk). Сделал простой пример: DCP_rijndael1.InitStr(‘p100’, TDCP_sha1); ShowMessage(DCP_rijndael1.EncryptString(‘Pass’)); DCP_rijndael1.Burn; Запустил его на D7 и D10. На D10 зашифрованная строка имеет вид: OPIGwVVQnzY= На D7 зашифрованная строка имеет вид: hfTlYw== То есть несмотря на то, что одни и те же данные шифровались с одним и тем же паролем, результат шифрования в D7 и D10 отличается. Провел аналогичный эксперемент с демкой FileEncrypt из состава библиотеки — результат то же самый: зашифрованный файл в D7 и D10 отличаются. Вопрос: Почему ? И что сделать, что… Подробнее »

Олег Третьяков
24/01/2018 19:59

Доброе время суток.
Ссылка на рассмотренный пример не работает

Lic
Lic
06/12/2020 17:44

День добрый.
Спасибо за статью, все описано доступно. Скажите, а DCP_rijndael работает только с параметром «MaxKeySize» = 256 ?
Мне надо было использовать ключ длинной 128 бит, установил 128, сбросился параметр в 256, посмотрел в исходниках, а там нет возможности работы с 128 битным ключиком. Есть ли версия сей библиотеки для работы с «MaxKeySize» = 128?

Lic
Lic
16/12/2020 00:20

Здравствуйте.
Спасибо за ответ. Я посмотрел другие библиотеки, так как я являюсь простым любителем, то искал библиотеку под Delphi 7 (ну привык я к ней), нашел TurboPower LockBox 3, релиз 3.4.1 поддерживает мою версию Delphi, то поставил именно её. Правда не нашел хороший хелп для «чайника», теперь разбираюсь.
Vlad, спасибо за ваш сайт, очень интересно читать доступно предоставленную информацию.