procedure TSigningForm.SignBtnClick(Sender: TObject);
var cont: PChar;
err: string;
hProv: HCRYPTPROV;
key: HCRYPTKEY;
alg: ALG_ID;
hash: HCRYPTHASH;
infile, outfile: file;
size: DWORD;
buf: array [0..511] of byte;
signature: PBYTE;
begin
{проверка существования выбранного файла}
if not FileExists(DataNameEdit.Text) then
begin
MessageDlg('Неверное имя файла!', mtError, [mbOK], 0);
exit;
end;
AssignFile(infile, DataNameEdit.Text);
…
"считываем" имя контейнера и подключаемся к нему
…
case HashRadioGroup.ItemIndex of
0: alg := CALG_MD5;
1: alg := CALG_SHA;
end;
CryptCreateHash(hProv, alg, 0, 0, @hash);
SaveDialog1.Title := 'Задайте имя файла для хранения подписанных данных';
if SaveDialog1.Execute then
begin
AssignFile(outfile, SaveDialog1.FileName);
rewrite(outfile, 1);
{записываем в файл идентификатор алгоритма хеширования}
BlockWrite(outfile, alg, 4);
reset(infile, 1);
size := FileSize(infile);
{записываем размер подписываемых данных}
BlockWrite(outfile, size, 4);
{пишем сами данные и вычисляем хеш:}
while not eof(infile) do
begin
BlockRead(infile, buf, 512, size);
BlockWrite(outFile, buf, size);
CryptHashData(hash, @buf, size, 0);
end;
CloseFile(infile);
{выясняем размер подписи}
CryptSignHash(hash, AT_SIGNATURE, nil, 0, nil, @size);
{создаем подпись}
GetMem(signature, size);
CryptSignHash(hash, AT_SIGNATURE, nil, 0, signature, @size);
BlockWrite(outfile, size, 4);
BlockWrite(outfile, signature^, size);
CloseFile(outfile);
end;
…
уничтожаем хеш-объект и освобождаем контекст
…
end;