procedure TMainForm.BitBtn1Click (Sender: TObject);
var
hProv: HCRYPTPROV;
KeyExchKey, SessionKey: HCRYPTKEY;
flag, keyLen: DWORD;
infile, outfile: file;
tmp: PBYTE;
buf: array [0..511] of byte;
alg: ALG_ID;
stream: boolean;
begin
…
подключение к криптопровайдеру
…
if ActionRadioGroup.ItemIndex = 0 {шифрование}
then
begin
OpenDlg.Title:= 'Укажите файл для шифрования';
if OpenDlg.Execute then AssignFile (infile, OpenDlg.FileName)
else exit;
OpenDlg.Title:= 'Укажите файл с открытым ключом обмена ключами получателя';
if OpenDlg.Execute then
begin
AssignFile (outfile, OpenDlg.FileName);
reset (outfile, 1);
keyLen:= FileSize (outfile);
GetMem (tmp, keyLen);
BlockRead (outfile, tmp^, keyLen);
CloseFile (outfile);
end
else exit;
CryptImportKey (hProv, tmp, keyLen, 0, 0, @KeyExchKey);
FreeMem (tmp, keyLen);
SaveDlg.Title:= 'Задайте имя файла для зашифрованных данных';
if SaveDlg.Execute then AssignFile (outfile, SaveDlg.FileName)
else exit;
rewrite (outfile, 1);
case AlgRadioGroup.ItemIndex of {установка алгоритма шифрования}
0: begin
alg:= CALG_RC2;	{алгоритм RC2}
stream:= false;	{блочный шифр}
end;
1: begin
alg:= CALG_RC4;	{алгоритм RC4}
stream:= true;	{поточный шифр}
end;
end;
CryptGenKey (hProv, alg, CRYPT_EXPORTABLE or CRYPT_CREATE_SALT, @SessionKey);	{создание сеансового ключа}
keyLen:= 128;	{размер буфера "с запасом"}
GetMem (tmp, keyLen);
CryptExportKey (SessionKey, KeyExchKey, SIMPLEBLOB, 0, tmp, @keyLen);
BlockWrite (outfile, keyLen, 4);	{запись в файл размера ключа}
BlockWrite (outfile, tmp^, keyLen);	{и самого зашифрованного ключа}
CryptDestroyKey (KeyExchKey);
keyLen:= 512; 	{размер буфера "с запасом"}
CryptGetKeyParam (SessionKey, KP_SALT, @buf, @keyLen, 0);
BlockWrite (outfile, keyLen, 4); 	{запись в файл размера солта}
BlockWrite (outfile, buf, keyLen); 	{и самого солт-значения}
if not stream then	{если шифр - блочный}
begin
//генерируем IV
keyLen:= 512; 	{размер буфера "с запасом"}
// запрос IV ради выяснения его размера
CryptGetKeyParam (SessionKey, KP_IV, @buf, @keyLen, 0);
CryptGenRandom (hProv, keyLen, @buf); 	{генерация IV}
CryptSetKeyParam (SessionKey, KP_IV, @buf, 0);
BlockWrite (outfile, keyLen, 4); 	{запись в файл размера IV}
BlockWrite (outfile, buf, keyLen); 	{и самого IV}
end;
reset (infile, 1);
while not eof (infile) do
begin	{собственно шифрование и запись в файл}
BlockRead (infile, buf, 496, keyLen);
CryptEncrypt (SessionKey, 0, eof (infile), 0, @buf, @keyLen, 512);
BlockWrite (outfile, buf, keyLen);
end;
CloseFile (infile);
CloseFile (outfile);
CryptDestroyKey (SessionKey);
end
else {расшифровывание}
begin	{получаем дескриптор своего ключа обмена ключами}
CryptGetUserKey (hProv, AT_KEYEXCHANGE, @KeyExchKey);
OpenDlg.Title:= 'Укажите файл с зашифрованными данными';
if OpenDlg.Execute then AssignFile (infile, OpenDlg.FileName)
else exit;
reset (infile, 1);
BlockRead (infile, keyLen, 4);	{читаем размер ключа}
GetMem (tmp, keyLen);
BlockRead (infile, tmp^, keyLen);	{читаем сам ключ}
CryptImportKey (hProv, tmp, keyLen, KeyExchKey, 0, @SessionKey);
FreeMem (tmp, keyLen);
CryptDestroyKey (KeyExchKey);
BlockRead (infile, keyLen, 4);	{читаем солт-значение}
BlockRead (infile, buf, keyLen);
CryptSetKeyParam (SessionKey, KP_SALT, @buf, 0);
keyLen:= 4;	{выясняем алгоритм шифрования}
CryptGetKeyParam (SessionKey, KP_ALGID, @alg, @keyLen, 0);
case alg of
CALG_RC2: stream:= false;
CALG_RC4: stream:= true;
end;
if not stream then	{если шифр - блочный}
begin
//читаем и устанавливаем IV
BlockRead (infile, keyLen, 4);
BlockRead (infile, buf, keyLen);
CryptSetKeyParam (SessionKey, KP_IV, @buf, 0);
end;
SaveDlg.Title:= 'Задайте имя файла для расшифрованных данных';
if SaveDlg.Execute then
begin
AssignFile (outfile, SaveDlg.FileName);
rewrite (outfile, 1);
while not eof (infile) do
begin	{собственно расшифровывание}
BlockRead (infile, buf, 512, keyLen);
CryptDecrypt (SessionKey, 0, eof (infile), 0, @buf, @keyLen);
BlockWrite (outfile, buf, keyLen);
end;
CloseFile (outfile);
end;
CloseFile (infile);
CryptDestroyKey (SessionKey);
end;
CryptReleaseContext (hProv, 0);
end;