Scalabium Software

SMExport advertising
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
 
SMImport suite
SMExport suite
Clarion Viewer
ABA Picture Convert
Metafile Convert
Excel Reader (dll)
DBISAM Password Recovery
DBExport tools
dBase Viewer
Viewer for TNEF-files (winmail.dat)
 
 


Contact to webmaster

 

Borland Software Code Gear Scalabium Delphi tips

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

SMExport/SMImport suites