Sample code for 30+ languages & platforms
Pascal (Lazarus/Delphi)

Duplicate PHP's openssl_encrypt and openssl_random_pseudo_bytes

See more OpenSSL Examples

Demonstrates how to duplicate PHP's openssl_encrypt function. (https://www.php.net/manual/en/function.openssl-encrypt.php)

Chilkat Pascal (Lazarus/Delphi) Downloads

Pascal (Lazarus/Delphi)
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;
  text: string;
  passphrase: string;
  ivBase64: string;
  bdKey: TBinData;
  sz: Integer;
  cipherText64: string;
  bd: TBinData;
  result: string;
  bdResult: TBinData;
  originalText: string;

begin
  success := False;

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

  //  Duplicates thw following PHP script:

  //  $text = "This is a test";
  //  $passphrase = "my password";
  //  $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length("AES-256-CBC"));
  //  $crypted = base64_encode($iv.openssl_encrypt($text, "AES-256-CBC", $passphrase, OPENSSL_RAW_DATA, $iv));
  //  echo $crypted;

  crypt := TCrypt2.Create;

  text := 'This is a test';
  passphrase := 'my password';

  //  AES is a block cipher.  The IV size for any block cipher is the size of the block, which is defined by the encryption algorithm. 
  //  For AES, the block size is always 16 bytes, regardless of key size (i.e. 128-bits, 192-bits, or 256-bits).
  //  Therefore, generate 16 random bytes for the IV.
  crypt.EncodingMode := 'base64';
  ivBase64 := crypt.GenRandomBytesENC(16);

  WriteLn('Generated IV = ' + ivBase64);

  //  Because we're doing AES-256-CBC, the key length must be 256-bits (i.e. 32 bytes).
  //  Given that our passphrase is a us-ascii string that can be shorter or longer than 32-bytes, we need to 
  //  somehow transform the passphrase to a 32-byte secret key.  We need to know what openssl_encrypt does.
  //  Here's the answer from the openssl_encrypt documentation:
  //  
  //  "If the passphrase is shorter than expected, it is silently padded with NUL characters; 
  //  if the passphrase is longer than expected, it is silently truncated."

  //  OK.... so let's pad or shorten to get a 32-byte key.
  bdKey := TBinData.Create;
  bdKey.AppendString(passphrase,'utf-8');

  sz := bdKey.NumBytes;
  if (sz > 32) then
    begin
      bdKey.RemoveChunk(32,sz - 32);
    end
  else
    begin
      bdKey.Clear();
      bdKey.AppendPadded(passphrase,'utf-8',False,32);
    end;

  //  Setup for encryption.
  crypt.CryptAlgorithm := 'aes';
  crypt.KeyLength := 256;
  crypt.SetEncodedIV(ivBase64,'base64');
  crypt.SetEncodedKey(bdKey.GetEncoded('base64'),'base64');

  //  Encrypt and base64 encode.
  cipherText64 := crypt.EncryptStringENC(text);

  //  The PHP code fragment above returns the base64 encoded bytes of the IV and the encrypted text.
  //  So let's do that..
  bd := TBinData.Create;
  bd.AppendEncoded(ivBase64,'base64');
  bd.AppendEncoded(cipherText64,'base64');
  result := bd.GetEncoded('base64');

  WriteLn('result = ' + result);

  //  Sample output:
  //  dN0vS1O0cWi5BbLAAY+NTf7bs3S27xzPf11RkG47sjs=

  //  Now let's decrypt from the output...

  //  Setup for decryption.
  crypt.CryptAlgorithm := 'aes';
  crypt.KeyLength := 256;
  crypt.SetEncodedKey(bdKey.GetEncoded('base64'),'base64');

  bdResult := TBinData.Create;
  bdResult.AppendEncoded(result,'base64');
  crypt.SetEncodedIV(bdResult.GetEncodedChunk(0,16,'base64'),'base64');

  //  Remove the IV (first 16 bytes) from the result.
  bdResult.RemoveChunk(0,16);
  success := crypt.DecryptBd(bdResult);
  originalText := bdResult.GetString('utf-8');

  WriteLn('original text = ' + originalText);


  crypt.Free;
  bdKey.Free;
  bd.Free;
  bdResult.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.