Sample code for 30+ languages & platforms
Lazarus Pascal

Example: Crypt2.RandomizeIV method

Demonstrates using a random initialization vector for AES GCM encryption.

Chilkat Lazarus Pascal Downloads

Lazarus Pascal
program ChilkatDemo;

// Demonstrates using the Chilkat Pascal wrapper via the C bridge DLL.
// Builds as a console application under Lazarus (FPC) or Delphi.

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
{$APPTYPE CONSOLE}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  CkDllLoader,
  Chilkat.BinData,
  Chilkat.Crypt2;

// ---------------------------------------------------------------------------

procedure RunDemo;
var
  success: Boolean;
  crypt: TCrypt2;
  K: string;
  AAD: string;
  PT: string;
  IV: string;
  cipherText: string;
  authTag: string;
  bdEncrypted: TBinData;
  concatenatedGcmOutput: string;
  decrypt: TCrypt2;
  bdFromEncryptor: TBinData;
  sz: Integer;
  extractedIV: string;
  extractedCipherText: string;
  expectedAuthTag: string;
  decryptedText: string;

begin
  success := False;

  //  This example assumes the Chilkat API to have been previously unlocked.
  //  See Global Unlock Sample for sample code.

  crypt := TCrypt2.Create;

  crypt.CryptAlgorithm := 'aes';
  crypt.CipherMode := 'gcm';
  crypt.KeyLength := 256;

  K := '000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F';
  AAD := 'feedfacedeadbeeffeedfacedeadbeefabaddad2';
  PT := 'This is the text to be AES-GCM encrypted.';

  //  Generate a random IV.
  crypt.RandomizeIV();
  IV := crypt.GetEncodedIV('hex');

  crypt.SetEncodedKey(K,'hex');

  success := crypt.SetEncodedAad(AAD,'hex');

  //  Return the encrypted bytes as base64
  crypt.EncodingMode := 'base64';
  crypt.Charset := 'utf-8';
  cipherText := crypt.EncryptStringENC(PT);
  if (crypt.LastMethodSuccess <> True) then
    begin
      WriteLn(crypt.LastErrorText);
      Exit;
    end;

  //  Get the GCM authenticated tag computed when encrypting.
  authTag := crypt.GetEncodedAuthTag('base64');

  WriteLn('Cipher Text: ' + cipherText);
  WriteLn('Auth Tag: ' + authTag);

  //  Let's send the IV, CipherText, and AuthTag to the decrypting party.
  //  We'll send them concatenated like this: [IV || Ciphertext || AuthTag]
  //  In base64 format.
  bdEncrypted := TBinData.Create;
  bdEncrypted.AppendEncoded(IV,'hex');
  bdEncrypted.AppendEncoded(cipherText,'base64');
  bdEncrypted.AppendEncoded(authTag,'base64');

  concatenatedGcmOutput := bdEncrypted.GetEncoded('base64');
  WriteLn('Concatenated GCM Output: ' + concatenatedGcmOutput);

  //  Sample output so far:

  //  -------------------------------------------------------------------------------------
  //  Now let's GCM decrypt...
  //  -------------------------------------------------------------------------------------

  decrypt := TCrypt2.Create;

  //  The values shared and agreed upon by both sides beforehand are: algorithm, cipher mode, secret key, and AAD.
  //  Sometimes the IV can be a value already known and agreed upon, but in this case the encryptor sends the IV to the decryptor.
  decrypt.CryptAlgorithm := 'aes';
  decrypt.CipherMode := 'gcm';
  decrypt.KeyLength := 256;
  decrypt.SetEncodedKey(K,'hex');
  decrypt.SetEncodedAad(AAD,'hex');

  bdFromEncryptor := TBinData.Create;
  bdFromEncryptor.AppendEncoded(concatenatedGcmOutput,'base64');

  sz := bdFromEncryptor.NumBytes;

  //  Extract the parts.
  extractedIV := bdFromEncryptor.GetEncodedChunk(0,16,'hex');
  extractedCipherText := bdFromEncryptor.GetEncodedChunk(16,sz - 32,'base64');
  expectedAuthTag := bdFromEncryptor.GetEncodedChunk(sz - 16,16,'base64');

  //  Before GCM decrypting, we must set the authenticated tag to the value that is expected.
  //  The decryption will fail if the resulting authenticated tag is not equal to the expected result.
  success := decrypt.SetEncodedAuthTag(expectedAuthTag,'base64');

  //  Also set the IV.
  decrypt.SetEncodedIV(extractedIV,'hex');

  //  Decrypt..
  decrypt.EncodingMode := 'base64';
  decrypt.Charset := 'utf-8';
  decryptedText := decrypt.DecryptStringENC(extractedCipherText);
  if (decrypt.LastMethodSuccess <> True) then
    begin
      //  Failed.  The resultant authenticated tag did not equal the expected authentication tag.
      WriteLn(decrypt.LastErrorText);
      Exit;
    end;

  WriteLn('Decrypted: ' + decryptedText);


  crypt.Free;
  bdEncrypted.Free;
  decrypt.Free;
  bdFromEncryptor.Free;

end;

// ---------------------------------------------------------------------------

begin

  try
    RunDemo;
  except
    on E: Exception do
      WriteLn('Unhandled exception: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  {$IFDEF MSWINDOWS}
  WriteLn('Press Enter to exit...');
  ReadLn;
  {$ENDIF}
end.