Среда : Delphi XE
Поставил перед собой цель разработки DLL-библиотеки шифрования файлов тремя алгоритмами(RC2, RC4, AES-256). Вот что получилось:
Код:
library Project1;
uses
Windows,
SysUtils,
dialogs,
Classes, WCrypt2;
var CRYPT_ALG, HASH_ALG : integer;
CRT_HANDLE : HCRYPTPROV;
HASH_HANDLE : HCRYPTHASH;
KEY_HANDLE : HCRYPTKEY;
BLOCKSIZE : byte;
{$R *.res}
function CreateHashKey(pass:shortstring):boolean;
begin
CryptCreateHash(CRT_HANDLE, HASH_ALG, 0, 0, @HASH_HANDLE);
CryptHashData(HASH_HANDLE, @pass[1], length(pass), 0);
CryptDeriveKey(CRT_HANDLE, CRYPT_ALG, HASH_HANDLE, 0, @KEY_HANDLE);
CryptDestroyHash(HASH_HANDLE);
result:=true;
{If (CryptCreateHash(CRT_HANDLE, HASH_ALG, 0, 0, @HASH_HANDLE) = false) or
(CryptHashData(HASH_HANDLE, @pass[1], length(pass), 0) = false) or
(CryptDeriveKey(CRT_HANDLE, CRYPT_ALG, HASH_HANDLE, 0, @KEY_HANDLE)=false) or
(CryptDestroyHash(HASH_HANDLE)=false) then
begin
result:=false;
exit;
end;}
end;
function EncryptFile(const Input_FilePath, OutPut_FilePath, Password : ShortString; const Algorithm : byte=0): byte; stdcall;
var InpFile, OutFile: File;
data: PByte;
dat:string;
ln: DWord;
d:string;
begin
try
//======================ОПРЕДЕЛЕНИЕ АЛГОРИТМА ШИФРОВАНИЯ===============================
case Algorithm of
0:
begin
CRYPT_ALG:=CALG_AES_256;
HASH_ALG:=CALG_SHA_256;
BLOCKSIZE:=16;
end;
1:
begin
CRYPT_ALG:=CALG_RC2;
HASH_ALG:=CALG_MD5;
BLOCKSIZE:=8;
end;
2:
begin
CRYPT_ALG:=CALG_RC4;
HASH_ALG:=CALG_MD5;
BLOCKSIZE:=1;
end;
else
begin
result:=1;
exit;
end;
end;
//=====================================================================================
//===========================ПРОВЕРКА СУЩЕСТВОВАНИЯ ВХОДНОГО ФАЙЛА=====================
if not FileExists(Input_FilePath) then
begin
result:=1;
exit;
end;
//=====================================================================================
//====================================ОСНОВНОЙ КОД=====================================
If not CryptAcquireContext(@CRT_HANDLE, nil, nil, PROV_RSA_AES, CRYPT_VERIFYCONTEXT) then
begin
result:=2;
exit;
end;
If not CreateHashKey(password) then
begin
result:=2;
exit;
end;
AssignFile(InpFile, Input_FilePath);
AssignFile(OutFile, OutPut_FilePath);
Reset(InpFile, 1);
Rewrite(OutFile, 1);
GetMem(data, 512);
while not eof(InpFile) do
begin
BlockRead(InpFile, data^, BLOCKSIZE, ln);
If not CryptEncrypt(KEY_HANDLE, 0, eof(InpFile), 0, data, @ln, ln) then
showmessage(inttostr(GetLastError));
BlockWrite(OutFile, data^, ln);
end;
FreeMem(data, 512);
CloseFile(InpFile);
CloseFile(OutFile);
CryptReleaseContext(CRT_HANDLE, 0);
result:=0;
except
result:=2;
end;
end;
function DecryptFile(const Input_FilePath, OutPut_FilePath, Password : ShortString; const Algorithm : byte=0): byte; stdcall;
begin
end;
exports EncryptFile, DecryptFile;
begin
end.
При вот таком использовании:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var hLib: HModule;
test: function (const Input_FilePath, OutPut_FilePath, Password : ShortString; const Algorithm : byte=0): byte; stdcall;
begin
memo1.Clear;
hLib:=LoadLibrary('project1.dll');
Test:=GetProcAddress(hLib, 'EncryptFile');
Memo1.Lines.Add(Inttostr(Test('TestIn.txt','TestOut1.txt','qwerty100500',strtoint(edit1.Text))));
Memo1.Lines.Add(Inttostr(Test('TestIn.txt','TestOut2.txt','qwerty100500',strtoint(edit2.text))));
Memo1.Lines.Add(Inttostr(Test('TestIn.txt','TestOut3.txt','qwerty100500')));
FreeLibrary(hLib);
end;
(В файле TestIn содержится запись "Абвгдейка")
Получаю такие выходные данные:
- TestOut1: ?лЁ›‹Ж°®алЁ›‹Ж°®
- TestOut2.txt: ^Хл!Н№ЕЮє
- TestOut3.txt : Абвгдейка
(В TestOut3 , Абвгдейка дополнена пробелами до 16 байт)
Т.е. получается, что RC2, RC4 шифруется коряво, а AES-256 вообще не шифрует. При чем во время шифования вываливаются сообщения (ShowMessage в цикле) с кодом ошибки 234, что означает недостаточное кол-во памяти для буфера(насколько я понял из MSDN). Но блин этого быть не может, ибо я пробовал и 5МБ выделять бестолку
Ну и собственно вопрос: где косяк и как его исправить?