Использование CryptoApi Delphi
От: Nikitko_Cent  
Дата: 30.12.12 07:35
Оценка:
Среда : Delphi XE.
Цель : решил сделать библиотеку для шифрования тремя разными алгоритмами (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);
        CryptEncrypt(KEY_HANDLE, 0, eof(InpFile), 0, data, @ln, ln);
        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.Txt: 'Абвгдейка'

Вот такие выходные файлы:

TestOut1 : ?лЁ›‹Ж°®алЁ›‹Ж°®
TestOut2 : ^Хл!Н№ЕЮє
TestOut3 : Абвгдейка
(В TestOut3 Абвгдейка дополнена прообелами (ну или неотображаемыми символами, хз) до 16 байт)


Т.е. Rc4 и Rc2 очень коряво шифрует, а AES256 вообще не шифрует. В memo выводится три нуля => функции отрабатывают до конца.
delphi cryptoapi rc2 rc4 aes-256
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.