Работа с криптобиблиотекой СКЗИ «Верба» через wbotho.dll

Библиотека wbotho.dll (wboth.dll) есть в дистрибутиве Вербы. Wboth.pas для работы с библиотекой из Delphi (Lazarus) вы можете скачать =>> тут <<= (версия может быть и не самая последняя, но зато рабочая)

Примеры использования:

1. Инициализация датчика случайных чисел:

Способ 1. Невидимый для пользователя, через файл asrkeyw.exe:


procedure InitAsrKey;
var HWind, H1: HWND;
Wind: String;
begin
Wind:='asrkeyw';
if ShellExecute(0,'open', PChar(Wind+'.exe'), nil, nil, SW_SHOWMINNOACTIVE) > 31 then begin
HWind:=0;
Repeat
HWind:=FindWindow(nil, PChar(Wind));
Until HWind<>0; //Ждемс
While not IsWindowVisible(HWind) do Application.ProcessMessages;
// Если не инициализирован датчик случайных чисел, то делаем инициализацию
Repeat
H1:=FindWindowEx(HWind, 0, 'Static', 'НАЖИМАЙТЕ ЛЮБЫЕ КЛАВИШИ ИЛИ ПОДВИГАЙТЕ МЫШЬЮ ...');
Until H1<>0;
while IsWindowVisible(H1) do begin
SendMessage(HWind,WM_LButtonDown,1,1);
SendMessage(HWind,WM_LButtonUp ,1,1);
Application.ProcessMessages;
end;
SendMessage (HWind, WM_CLOSE, 0, 0);
end;
end;

Способ 2. Используя окошко Вербы:


function InitVerbaKey: string;
var err_code: Word;
begin
err_code:=InitRndm(PChar('A:\'), 1);
Result:=GetVerbaErrorStr(err_code));
end;

2. Подпись файла:


function Sign(WorkFile: String): Boolean;
var err_code: Word;
begin
Result:=True;
// Инициализация ключа
InitKey(Pointer('A:'), '');
err_code := SignInit(PChar('A:\'), PChar('Путь_до_справочников'));
if err_code = 0 then begin
// Подпись файла
// SignKey это идентификатор ключа отправителя в формате XXXX SSSSSS 01
err_code := SignFile(PChar(WorkFile), PChar(WorkFile), PChar(SignKey));
if (err_code <> 0) then Result:=True;
end else
// не инициализировали по какой то причине
Result:=False;
// Завершение
SignDone;
ResetKeyEx(PChar(SignKey), 1);
end;

3. Шифрование файла:


function TForm1.Crypto(WorkFile, CryptoAbonent, CryptoKey: String): Boolean;
var err_code, from: Word;
CAbonent: array [0..1] of word;
begin
Result:=True;
// Инициализация ключа
InitKey(Pointer('A:'), '');
err_code := CryptoInit(PChar('A:\'), PChar('Путь_до_справочников'));
if err_code = 0 then begin
// Шифрование файла
// CryptoAbonent = На кого шифруем
// CryptoKey = это идентификатор ключа получателя в формате XXXX SSSSSS
CAbonent[0]:=StrToInt(CryptoAbonent); CAbonent[1]:=0; from:=StrToInt(copy(CryptoKey, 1, 4));
Result := EnCryptFile(PChar(WorkFile), PChar(WorkFile), from, @CAbonent, PChar(copy(CryptoKey, 5, 6)));
end else
// не инициализировали по какой то причине
Result:=False;
// Завершение
CryptoDone;
ResetKeyEx(PChar(CryptoKey), 1);
end;

5. Расшифровка файла:


procedure pDeCryptFile (mFile, CryptoAbonent: String);
var err_code: Word;
sender_key: array [0..SERTIFICAT_LENGTH] of byte;
begin
sender_id:=' ';
// Инициализация датчика случайных чисел
err_code:=InitRndm(PChar('A:\'), 1);
if err_code = 0 then begin
// Инициализация криптоключа
err_code:=CryptoInit(PChar('A:'), 'Путь_до_справочников'));
if err_code = 0 then begin
// Получение ID отправителя
err_code:=GetFileSenderID(PChar(mFile), PChar(sender_id));
if err_code = 0 then begin
// Инициализация открытого ключа
err_code:=ExtractKey(PChar(ExtractFileDir('Путь_до_справочников'), pchar(sender_ID), @sender_key);
if err_code = 0 then begin
// Расшифровка файла
// CryptoAbonent = идентификатор ключа получателя("XXXXSSSSSS")
err_code:=DeCryptFileEx (PChar(mFile), PChar(mFile), PChar(CryptoAbonent), @sender_key);
end;
end;
end;
// Завершение работы
CryptoDone;
end;
end;

6. Убираем подпись с файла, попутно пытаясь его разархивировать, используя библиотеку mpacker.dll:


function DeCompressFile (infile, outfile: LPSTR):WORD; cdecl external 'mpacker.dll' name 'DeCompressFile';
procedure pDeSignFile (mFile: String);
var err_code: Word;
begin
// Попытка разархивировать файл
DeCompressFile (PChar(mFile), PChar(mFile));
// Инициализация датчика случайных чисел
err_code:=InitRndm(PChar('A:\'), 1);
// Инициализация криптоключа
if err_code = 0 then begin
// Инициализация ключа подписи
err_code:=SignInit(PChar('A:'), PChar('Путь_до_справочников'));
if err_code = 0 then
// Удаление подписи
err_code:=DelSign(PChar(mFile), 255);
// Завершение работы
SignDone;
end;

7. Дополнительно. Что бы не использовать дисковод и диск А:, вы можете смапировать любую папку жесткого диска или флешки на диск B:. Подпись будет осуществляться в разы быстрее:


function MapDisk(PathMap: String): Boolean;
var CurrentMap: String;
function DiskPresent(Letter : Char) : Boolean;
Begin
Result:= ((GetLogicalDrives AND (Ord(Letter)-64)) > 0);
End;
function Subst: Boolean;
begin
Result:=True;
if (not DefineDosDevice(0, PChar(DiskForSign + ':'), PChar(PathMap))) then begin
AddLog('Не удалось подключить криптографический диск [' + PathMap + '].');
Result:=False;
end else
AddLog('На устройство ' + DiskForSign + ' смапировано ' + PathMap);
end;
function SubstQuery: string;
var buff: array[0..256] of char;
begin
buff[0] := #0;
QueryDosDevice(PChar(DiskForSign + ':'), buff, 256);
Result := StrPas(buff);
if Copy(Result,1,4) = '\??\' then Result := Copy(Result, 5, Length(Result)) else Result:='';
end;
begin
Result:=False;
if DiskPresent(DiskForSign[1]) then begin
CurrentMap := SubstQuery;
if PathMap = CurrentMap then Result:=True
else
if (DefineDosDevice(DDD_REMOVE_DEFINITION, PChar(DiskForSign + ':'), PChar(CurrentMap))) then
Result:=Subst
end else Result:=Subst;
end;

Добавить комментарий

Ваш e-mail не будет опубликован.