program dp_182529;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
DECUtil, DECCipher, DECHash, DECFmt;
var
ACipherClass: TDECCipherClass = TCipher_Rijndael;
ACipherMode: TCipherMode = cmCBCx;
AHashClass: TDECHashClass = THash_Whirlpool;
ATextFormat: TDECFormatClass = TFormat_Mime64;
AKDFIndex: LongWord = 1;
function Encrypt(
const AText:
String;
const APassword:
String ):
String;
var
LSalt: Binary;
LData: Binary;
LPass: Binary;
LCipher: TDECCipher;
begin
LCipher := ValidCipher(
{ CipherClass } ACipherClass ).
{ > } Create;
try
LSalt := RandomBinary( 16 );
LPass := ValidHash(
{ HashClass } AHashClass ).
{ > } KDFx(
{ Data } APassword[1],
{ DataSize } Length( APassword ) * SizeOf( APassword[1] ),
{ Seed } LSalt[1],
{ SeedSize } Length( LSalt ),
{ MaskSize } LCipher.Context.KeySize,
{ Format } TFormat_Copy,
{ Index } AKDFIndex );
LCipher.Mode := ACipherMode;
LCipher.Init( LPass );
SetLength( LData, Length( AText ) * SizeOf( AText[1] ) );
LCipher.Encode(
{ Source } AText[1],
{ Dest } LData[1],
{ DataSize } Length( LData ) );
Result := ValidFormat(
{ FormatClass } ATextFormat ).
{ > } Encode(
{ Value } LSalt + LData + LCipher.CalcMAC );
finally
LCipher.Free;
ProtectBinary( LSalt );
ProtectBinary( LData );
ProtectBinary( LPass );
end;
end;
function Decrypt(
const AText:
String;
const APassword:
String ):
String;
var
LSalt: Binary;
LData: Binary;
LCheck: Binary;
LPass: Binary;
LLen: Integer;
LCipher: TDECCipher;
begin
LCipher := ValidCipher(
{ CipherClass } ACipherClass ).
{ > } Create;
try
LSalt := ValidFormat(
{ FormatClass } ATextFormat ).
{ > } Decode(
{ Value } AText );
LLen := Length( LSalt ) - 16 - LCipher.Context.BufferSize;
LData := System.Copy( LSalt, 17, LLen );
LCheck := System.Copy( LSalt, LLen + 17, LCipher.Context.BufferSize );
SetLength( LSalt, 16 );
LPass := ValidHash(
{ HashClass } AHashClass ).
{ > } KDFx(
{ Data } APassword[1],
{ DataSize } Length( APassword ) * SizeOf( APassword[1] ),
{ Seed } LSalt[1],
{ SeedSize } Length( LSalt ),
{ MaskSize } LCipher.Context.KeySize,
{ Format } TFormat_Copy,
{ Index } AKDFIndex );
LCipher.Mode := ACipherMode;
LCipher.Init(
{ Key } LPass );
SetLength( Result, LLen
div SizeOf( AText[1] ) );
LCipher.Decode(
{ Source } LData[1],
{ Dest } Result[1],
{ DataSize } LLen );
if LCheck <> LCipher.CalcMAC
then
raise Exception.Create( '
Invalid data' );
finally
LCipher.Free;
ProtectBinary( LSalt );
ProtectBinary( LData );
ProtectBinary( LCheck );
ProtectBinary( LPass );
end;
end;
procedure Main;
var
LText:
string;
LPass:
string;
begin
LText := '
The quick brown fox jumps over the lazy dog';
LPass := '
U5r5klO0zwu674593';
Writeln( '
Encode Test: ', Encrypt( LText, LPass ) );
Writeln( '
Decode Test: ', Decrypt( Encrypt( LText, LPass ), LPass ) );
end;
begin
try
Main;
except
on E:
Exception do
Writeln( E.ClassName, '
: ', E.
Message );
end;
ReadLn;
end.