Lazarus Pascal
Lazarus Pascal
Example: Crypt2.RandomizeIV method
Demonstrates using a random initialization vector for AES GCM encryption.Chilkat Lazarus Pascal Downloads
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.