1. Technology

Crypting Your Delphi Application INI (Configuration) Files

Hide The Content Of Your INI Files From Unwanted Eyes.

By

In most of my applications I'm using INI files to store configuration options.

INI files can be easily manipulated using the TIniFile or TMemIniFile classes implemented in the "inifiles.pas" unit.

INI files are text based documents with a simple structure. A user can open your INI files using Notepad or similar applications and see or manually change the content.

For one particular situation I wanted to somehow hide the content of the INI file. Yes, INI files are not to be used to store critical data, but in this case I only simply wanted to have a no-eye situation.

Simple INI Encryption

I've been looking for a simple crypt / uncrypt function that will allow me to easily scramble a string value (the content of the INI file) and unscramble it back.

The "Encrypting and Decrypting strings in Delphi" provides a simple encryption / decryption algorithm for string values.

Let's see how the "save" INI file method looks:

procedure SaveCryptedConfig;
const
  iniLocation = 'c:\cryptedini.ini';
var
  mini : TMemIniFile;
  sl : TStrings;
  cnt : integer;
begin
  sl := TStringList.Create;
  mini := TMemIniFile.Create(iniLocation);
  try
    //add data to mini using
    //WriteString, WriteInteger, ...


    mini.GetStrings(sl);

    for cnt := 0 to -1 + sl.Count do
      sl[cnt] := EnDeCrypt(sl[cnt]);

    //SetStrings and UpdateFile would mess up the thing so directly
    //saving using TStringList (SetStrings tries to read as ini file cryptig is not)


    sl.SaveToFile(iniLocation);
  finally
    FreeAndNil(sl);
    FreeAndNil(mini);
  end;
end;
The TMemIni class is used to store values in an ini-like structure to a "mini" TMemIniFile instance.

After all values are written (in memory) to the mini, the GetStrings method copies the INI file data currently stored in memory into a pre-existing string list.

Next, each line in the string list is hashed (crypted) using the "EnDeCrypt" function.

Finally, the SaveToFile method of the TStringList is used to save the INI file. The SetStrings (to populate the memory buffer with contents of a string list) should not be used as it would not properly "set" our cryped string values. This is also the reason why "UpdateFile" method is not used.

If you open the "c:\cryptedini.ini" using Notepad it looks like an ini but strings are "a mess". Exactly what needed!

Let's now see how the "load" INI file method looks:

procedure LoadCryptedConfig;
const
  iniLocation = 'c:\cryptedini.ini';
var
  mini : TMemIniFile;
  sl : TStrings;
  cnt : integer;
begin
  sl := TStringList.Create;

  //loading this file makes no sense as it is hashed
  mini := TMemIniFile.Create(iniLocation);
  try
    sl.LoadFromFile(iniLocation); //crypted one

    for cnt := 0 to -1 + sl.Count do
      sl[cnt] := EnDeCrypt(sl[cnt]);

    mini.SetStrings(sl);

    //read and apply data from mini using
    //ReadString, ReadInteger, ...

  finally
    FreeAndNil(sl);
    FreeAndNil(mini);
  end;
end;
The TMemIniFile.Create(iniLocation) makes no sense as it would load a hashed ini (inside Create there's a call to a private LoadValues method which presumes the INI structure is as expected).

Therefore, again, a string list is used to load the file. After decrypting the lines the SetStrings method the TMemIni is used to put in the values. Finally you read the INI as you normally would using any or ReadInteger or ReadString or alike methods.

Finally, here's the EnDeCrypt function :

function EnDeCrypt(const Value : String) : String;
var
  CharIndex : integer;
begin
  Result := Value;
  for CharIndex := 1 to Length(Value) do
    Result[CharIndex] := Chr(not(Ord(Value[CharIndex])));
end;
As said, if you need to really hide some configuration options from the user you would probably not use INI file at all. In my scenario simply making the INI not easily readable did the trick.

©2014 About.com. All rights reserved.