Sign in Join
Wiki copytemporary

Revision 1 of 2, by WikiArchive on 11-4-2026. The page as it is now.

CryptINI

Contents

CryptINI

Screenshots

latest testcryptini.jpg

testcryptini1.jpg

Purpose

TCryptIni is a TiniFile implementation that is resistant to tampering. In normal (PlainTextMode = FALSE) mode, any calls to Write values are accompanied by an embedded MD5 hash value (and also reversed then Base64/IDEA Encrypted) This is invisible in normal use (i.e. read methods return normal results) but there are added methods to internally verify any entries. It also is able to write a standard ident section containing various details including authorship and copyright. A single function allows you to check on app startup whether this section has been altered. It also includes a useful 'First Run' functionality. It's intended purpose is to store information that cannot be easily altered in a text editor (such as HiScores etc) by a weekend scripter. The WriteInteger method is the most secure as it double-encrypts as well as embedding an MD5Hash value as a checksum. Very handy to save scores etc. It is paired with ReadInteger and VerifyInteger

Disclaimer

This unit does not claim to pass any security tests nor be used in any environment where a moderate-level hacker could circumvent it.

Encryption

By Default CryptINI uses the DCPCrypt package for string encryption. The mode is IDEA cipher with an MD5 hash for the key. The EncryptINI and DecryptINI methods use DCPCrypt RC4 Cipher (With SHA hash) There is a $DEFINE USE_DCPCRYPT directive at the top of the ucryptini file.

If this DEFINE is commented out, then CryptINI will default to BASE64 string encryption, which is weaker. Encrypt/DecryptINI methods will be unavailable. You can then delete any requirement for dcpcrypt in the project inspector.

FPC versions

Starting in FPC V3.1.1 there are additional options in TINIFile which are implemented in TCryptINI if the FPC Version >= 3.1.1 is detected.

Use and Example Code

Simple use

Instead of

pascal
Uses Inifiles;
    TForm1.SomeProcedure;
    Var INI:TIniFile;
    begin
     INI := TIniFile.Create(ChangeFileExt(Application.EXEName, '.cfg'));
    end;

You do: (note the 'uses ucryptini')

pascal
Uses ucryptini;
    TForm1.SomeProcedure;
    Var INI:TCryptIniFile;
    begin
     INI := TCryptIniFile.Create(ChangeFileExt(Application.EXEName, '.cfg'));
    end;
pascal
INI.PlainTextMode=True;
    INI.SectionHashing:=False;

.. then TCryptINI will behave exactly as TIniFile does, so you can drop it into existing code without changing an existing INI file.

Using the WriteIdent etc in Form.Create

pascal
procedure TForm1.FormCreate(Sender: TObject);
    const
      C_KEYPHRASE = 'I do like to be beside the seaside'; // Move this to the top of the unit
    Begin
     ...other code
     // Initialise the encrypted config file
     INI := TCryptIniFile.Create(ChangeFileExt(Application.EXEName, '.cfg'));
    
     // First ever run.  INI is absent
     If INI.IsVirgin then INI.WriteIdent('minesadorada','(c)2016','minesadorada@charcodelvalle.com','Creative Commons',TRUE);
    
     if NOT INI.VerifyIdent('5b319674f5cb55f3ed1e404e33c25868') then // I got this from the INI file
       ShowMessage('This is not a genuine copy of ' + Application.Title + '!')
     else INI.Deflower; // If not Deflowered then the default ini is used.
    
     // After first run, use the encrypted version
     If NOT INI.IsVirgin then
     begin
       INI.DecryptINI(TRUE,C_KEYPHRASE);
     // Check the unencrypted version..
       if NOT INI.VerifyIdent('5b319674f5cb55f3ed1e404e33c25868') then // I got this from the INI file
       ShowMessage('This is not a genuine copy of ' + Application.Title + '!');
     end;
     INI.KeyPhrase:=C_KEYPHRASE; // for subsequent read/writes
     ...other code
    end;
    
    procedure Tmainform.FormDestroy(Sender: TObject);
    const
      C_KEYPHRASE = 'I do like to be beside the seaside'; // Move this to the top of the unit
    Begin
     ...other code
      INI.EncryptINI(TRUE,C_KEYPHRASE);
      ...other code
    end;
pascal
// Use the MD5 value from the INI file (use your own!)
    If INI.VerifyIdent('92abf0deecbb25c435bff507a396d92a') then
      ShowMessage('Ident verified OK') // do nothing
    else
      ShowMessage('Ident failed verification'); // Warning message/exit
pascal
If INI.IsVirgin then // note that doing the test Deflowers the app by default
       ShowMessage('First time run of this app');

(by default it is set to FALSE)

pascal
INI.PlainTextMode:=TRUE;
    INI.WriteString('MySection', 'String', 'MyString'); // just writes normally
pascal
INI.WriteInteger('MySection', 'Integer',1000);

This is so that CryptINI can deal with Integers specially Using CryptINI in either mode, this is invisible in use (i.e. don't add a + to the ident for any methods)

pascal
INI.ReadUnencryptedString
    INI.WriteUnencryptedString
    INI.ReadUnEncryptedInteger
    INI.WriteUnencryptedInteger
pascal
INI.IsVirgin
    INI.Deflower
    INI.ReFlower (useful for testing)

Encrypting/Decrypting the whole INI file

This uses a different cipher and hash method, so is extra-secure.

Original IniFiles methods and properties

Just use them as normal. Note: you can mix-and-match Plaintext and Encrypted in the same INI file. Just toggle the property PlainTextMode before Writing/Reading

Testing App/Demo

Documentation

Licence

Download

Package Installation


Minesadorada


From the Free Pascal wiki, page "CryptINI", as the Internet Archive kept it on 2025-04-17. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.