Как защитить свои файлы от посторонних глаз? Конечно можно просто заархивировать его Winrar’ом и поставить пароль, но этот метод явно не для нас. Ниже я покажу как при помощи симметричного шифрования зашифровать любой интересующий нас файл с помощью пароля, после чего благополучно его расшифровать. В симметричных криптосистемах для шифрования и расшифрования используется один и тот же ключ, отсюда и название — симметричные.
Создание программы шифрование файлов
Создадим форму с 2 кнопками, полем для пароля и TProcessBar для отображения хода выполнения шифрования файла.
Бросим на форму еще 2 компонента: OpenDialog и SaveDialog для работы с диалогом открытия и сохранения расшифрованного файла.
Для кнопки Зашифровать присвоим следующий код:
procedure TFormMain.Button1Click(Sender: TObject); var d: byte; i: integer; Files,NewFiles: TStream; begin Button1.Enabled:=false; Button2.Enabled:=false; if OpenDialog1.Execute then begin Files:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead); NewFiles:=TFileStream.Create(OpenDialog1.FileName+'.shifr',fmCreate); ProgressBar1.Max:=Files.Size; for i:=0 to Files.Size - 1 do begin Files.Position:=i; NewFiles.Position:=i; Files.Read(d,1); d:=d+Password; NewFiles.Write(d,1); ProgressBar1.Position:=i; Application.ProcessMessages; if Application.Terminated then Break; end; ProgressBar1.Position:=i; NewFiles.Free; Files.Free; end; ProgressBar1.Position:=0; ShowMessage('Файл закодирован!'); Button1.Enabled:=true; Button2.Enabled:=true; end;
Из данного кода мы видим, что открывая файл мы побайтно проходим его, меняя значение байта прибавляя к нему некий Password который определен в нашей программе как функция. Из-за того то наш пароль может принимать не только числовое значение, мы должно сделать так чтобы наш пароль в программе имел именно числовой вид, для этого мы создаем отдельную функцию которая будет преобразовывать наш пароль в числовой вид.
Функция Password:
Function TFormMain.Password:integer; var i:integer; begin for i:=0 to Length(EditPass.Text) do result:=result+Ord(EditPass.Text[i]); end;
Теперь аналогично нашей процедуре шифрования файла, напишем код для расшифровки нашего файла:
procedure TFormMain.Button2Click(Sender: TObject); var d: byte; i: integer; Files,NewFiles: TStream; begin Button1.Enabled:=false; Button2.Enabled:=false; if OpenDialog1.Execute then if SaveDialog1.Execute then begin Files:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead); NewFiles:=TFileStream.Create(SaveDialog1.FileName,fmCreate); ProgressBar1.Max:=Files.Size; for i:=0 to Files.Size-1 do begin Files.Position:=i; NewFiles.Position:=i; Files.Read(d,1); d:=d-Password; NewFiles.Write(d,1); ProgressBar1.Position:=i; Application.ProcessMessages; if Application.Terminated then Break; end; ProgressBar1.Position:=i; NewFiles.Free; Files.Free; end; ProgressBar1.Position:=0; ShowMessage('Файл раскодирован!'); Button1.Enabled:=true; Button2.Enabled:=true; end;
Вот и все. Пусть этот метод далек от совершенства, но сегодня мы с вами научились на практике применять симметричное шифрование файлов, а так же в увидели работу ProcessBar и Application.ProcessMessages которые позволяют нам увидеть состояние шифровки\дешивровки в текущий момент времени. Иначе наша программа, визуально зависала до тез пор пока не завершила обработку файла, если конечно мы не выполняли бы данные процедуры в отдельном потоке.
Для наглядности предлагаю вам скачать готовый исходник с данной программой: Скачать
Еще есть библиотека DCPcrypt. Сам пока еще не пользовался но он вроде шифрует md, sha и т.д. + еще не только айл можно зашифровать но и текст или строку.
http://wiki.freepascal.org/DCPcrypt
Возможно как-нибудь попробую данную библиотеку и опишу процесс
А можно ли как то добавить пункт в контекстное меню? Просто тогда бы это была очень интересная и простая программа.
Конечно можно, с помощью манипуляций с реестром программным путем.
Нужно добавить еще одно условие, на тот случай «если поле ввода пароля пустое, значит ничего не происходит(кнопки заблокированы)»:
if Edit1.Text = » then exit;
И еще, можно добавить после «ProgressBar1.Position:=i;», что-то типа такого:
Label1.Caption:=’Идет процесс шифрования’+IntToStr(i);
так более наглядно, ProgressBar заполняется и циферки бегут
Все работает от шифровки до расшифровки, но есть вопрос, почему не работает, если файл сразу шифровать, а не создавать отдельный файл в который постепенно записываются байты первого?
Для этого, предварительно нужно будет выгрузить файл в память и перезаписать существующий. Или проще после записи удалять старый.
Данная статья показывает пример, но не руководство к действиям.
Для шифрования файлов, я бы использовал например AES 256.