Scalabium Software

SMReport Autogenerated
Knowledge for your independence'.
Home Delphi and C++Builder tips


#172: How crypt/decrypt the file in Crypt API?

Hello,

in last time I worked a lot with crypt algorithmes and today I want to post the new tip with sample code where I'll show how you may crypt and decrypt any file using standard Crypt API which is available in MS Windows.

The standard task is to encrypt the file content using some password. And as result, the encrypted file nobody can decrypt if he/she don't provide the valid password.

The code below allow to solve this task:

procedure CryptFile(const SourceFileName, DestinationFileName, Password: string; ToCrypt: Boolean);
var
  hProv: HCRYPTPROV;
  hash: HCRYPTHASH;
  key: HCRYPTKEY;

  Buffer: PByte;
  len: dWord;
  fsIn, fsOut: TFileStream;
  IsEndOfFile: Boolean;
begin
  {get context for crypt default provider}
  CryptAcquireContext(@hProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
  {create hash-object (SHA algorithm)}
  CryptCreateHash(hProv, CALG_SHA, 0, 0, @hash);
  {get hash from password}
  CryptHashData(hash, @Password[1], Length(Password), 0);
  {create key from hash by RC4 algorithm}
  CryptDeriveKey(hProv, CALG_RC4, hash, 0, @key);
  {destroy hash-object}
  CryptDestroyHash(hash);

  {open source+destination files}
  fsIn := TFileStream.Create(SourceFileName, fmOpenRead or fmShareDenyWrite);
  fsOut := TFileStream.Create(DestinationFileName, fmCreate);
  try
    {allocate buffer to read content from source file}
    GetMem(Buffer, 512);

    repeat
      IsEndOfFile := (fsIn.Position >= fsIn.Size);
      if IsEndOfFile then break;

      {read content from source file}
      len := fsIn.Read(Buffer^, 512);

      if ToCrypt then
        {crypt buffer}
        CryptEncrypt(key, 0, IsEndOfFile, 0, Buffer, @len, len)
      else
        {decrypt buffer}
        CryptDecrypt(key, 0, IsEndOfFile, 0, Buffer, @len);

      {write changed buffer to destination file}
      fsOut.Write(Buffer^, len)
    until IsEndOfFile;

    {release memory allocated for buffer}
    FreeMem(Buffer, 512);
  finally
    fsIn.Free;
    fsOut.Free;
  end;

  {release the context for crypt default provider}
  CryptReleaseContext(hProv, 0);
end;

And sample to use:
- to encrypt file:
CryptFile('c:\datafile.txt', 'd:\encrypted.dat', 'peter', True);

- to decrypt file
CryptFile('d:\encrypted.dat', 'c:\datafile.txt', 'peter', False);

Of course, you may change the code above to accept the any streams (not only file streams) and/or to use another algorithmes.

PS: please note to compile the code above you need header files for Crypt API. for example, you may use the wcrypt2.pas unit which is available at ftp://ftp.delphi-jedi.org/api/CryptoAPI2.zip


Published: February 27, 2007

See also
 
DBISAM Password Recovery
Paradox Password Recovery
DBExport tools
Paradox to Text converter
Database Information Manager
ExcelFile Viewer
SMMsg suite
SMDBGrid
ABA Database Convert
Word Web-stream
 
 


Contact to webmaster

 

Borland Software Code Gear Scalabium Delphi tips

Copyright© 1998-2024, Scalabium Software. All rights reserved.
webmaster@scalabium.com

SMExport advertising