Sample code for 30+ languages & platforms
Delphi ActiveX

Example: Crypt2.RandomizeIV method

Demonstrates using a random initialization vector for AES GCM encryption.

Chilkat Delphi ActiveX Downloads

Delphi ActiveX
uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Chilkat_TLB;

...

procedure TForm1.Button1Click(Sender: TObject);
var
success: Integer;
crypt: TChilkatCrypt2;
K: WideString;
AAD: WideString;
PT: WideString;
IV: WideString;
cipherText: WideString;
authTag: WideString;
bdEncrypted: TChilkatBinData;
concatenatedGcmOutput: WideString;
decrypt: TChilkatCrypt2;
bdFromEncryptor: TChilkatBinData;
sz: Integer;
extractedIV: WideString;
extractedCipherText: WideString;
expectedAuthTag: WideString;
decryptedText: WideString;

begin
success := 0;

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

crypt := TChilkatCrypt2.Create(Self);

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 <> 1) then
  begin
    Memo1.Lines.Add(crypt.LastErrorText);
    Exit;
  end;

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

Memo1.Lines.Add('Cipher Text: ' + cipherText);
Memo1.Lines.Add('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 := TChilkatBinData.Create(Self);
bdEncrypted.AppendEncoded(IV,'hex');
bdEncrypted.AppendEncoded(cipherText,'base64');
bdEncrypted.AppendEncoded(authTag,'base64');

concatenatedGcmOutput := bdEncrypted.GetEncoded('base64');
Memo1.Lines.Add('Concatenated GCM Output: ' + concatenatedGcmOutput);

// Sample output so far:

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

decrypt := TChilkatCrypt2.Create(Self);

// 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 := TChilkatBinData.Create(Self);
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 <> 1) then
  begin
    // Failed.  The resultant authenticated tag did not equal the expected authentication tag.
    Memo1.Lines.Add(decrypt.LastErrorText);
    Exit;
  end;

Memo1.Lines.Add('Decrypted: ' + decryptedText);
end;