You are not logged in.
Please see example code (simple console project, please copy and save as Project2.dpr and run):
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes,
SynCrypto;
function convertSB (const arg: AnsiString): TBytes;
var
i: integer;
begin
Setlength(Result, Length(arg));
for i := 0 to length(arg) - 1 do
begin
result[i] := ord (arg [i + 1]);
end;
end;
function EASstreamCrypt(aEASClass: TAESAbstractClass; const aInStream, aOutStream: TStream; const aPassword: TBytes): Integer;
var
aKeySize: Integer;
lAES : TAESAbstract;
lBytesIn : TBytes;
lBytesOut : TBytes;
begin
aKeySize := Length(aPassword) shl 3;
Assert((aKeySize = 128) or (aKeySize = 192) or (aKeySize = 256));
lAES := aEASClass.Create(aPassword, aKeySize);
try
SetLength(lBytesIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lBytesIn[0], aInStream.Size);
lBytesOut := lAES.EncryptPKCS7(lBytesIn, True);
Result := Length(lBytesOut);
aOutStream.Write(lBytesOut[0], Length(lBytesOut));
finally
lAES.Free;
end;
end;
function EASstreamDecrypt(aEASClass: TAESAbstractClass; aInStream, aOutStream: TStream; const aPassword: TBytes):
Integer;
var
aKeySize: Integer;
lAES : TAESAbstract;
lBytesIn : TBytes;
lBytesOut : TBytes;
begin
aKeySize := Length(aPassword) shl 3;
Assert((aKeySize = 128) or (aKeySize = 192) or (aKeySize = 256));
lAES := aEASClass.Create(aPassword, aKeySize);
try
SetLength(lBytesIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lBytesIn[0], aInStream.Size);
lBytesOut := lAES.DecryptPKCS7(lBytesIn, True);
Result := Length(lBytesOut);
aOutStream.Write(lBytesOut[0], Length(lBytesOut));
finally
lAES.Free;
end;
end;
procedure streamCryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
EASstreamCrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
procedure streamDecryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
EASstreamDecrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
procedure SelfTest;
var
decodedString: String;
inputString: string;
InStr, OutStr : TMemoryStream;
InputStringStream : TStringStream;
lInStrStream, lOutStrStream : TStringStream;
lPasswordBytes: TBytes;
begin
inputString := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque hendrerit augue quis lacus efficitur,' +
' sollicitudin tempor sapien dapibus. Vivamus quis neque congue, imperdiet nisi nec, hendrerit nulla.' +
' Ut quis dolor eget sapien sodales faucibus vel at turpis. Aenean sed varius arcu.';
lPasswordBytes := convertSB('01234567890123456789012345678901');
InStr := TMemoryStream.Create;
OutStr := TMemoryStream.Create;
InputStringStream := TStringStream.Create(inputString, TEncoding.Unicode);
try
// -------------------------------------------------------------------------
// TEST 1
InStr.Clear;
OutStr.Clear;
InStr.CopyFrom(InputStringStream, 0);
InStr.Position := 0;
// crypt
EASstreamCrypt(TAESCBC, InStr, OutStr, lPasswordBytes);
//decrypt
InStr.Clear;
EASstreamDecrypt(TAESCBC, OutStr, InStr, lPasswordBytes);
decodedString := 'empty';
decodedString := Copy(PChar(InStr.Memory), 1, Length(inputString));
Assert(decodedString = inputString);
// TEST 1 PASSED
// -------------------------------------------------------------------------
// TEST 2 with simple wrapper
InStr.Clear;
OutStr.Clear;
InStr.CopyFrom(InputStringStream, 0);
InStr.Position := 0;
// crypt
streamCryptWrapper(InStr, OutStr, lPasswordBytes);
InStr.Clear;
// decrypt
streamDecryptWrapper(OutStr, InStr, lPasswordBytes); // <--- ESynCrypto exception: TAESCBC.DecryptPKCS7: Invalid content
decodedString := 'pustka';
InStr.Position := 0;
decodedString := Copy(PChar(InStr.Memory), 1, Length(inputString));
Assert(decodedString = inputString);
finally
InStr.Free;
OutStr.Free;
InputStringStream.Free;
end;
end;
begin
try
SelfTest;
except
on E: ESynCrypto do
Writeln('ESynCrypto: ', E.Message);
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
This line raise exception:
streamDecryptWrapper(OutStr, InStr, lPasswordBytes); // <--- ESynCrypto exception: TAESCBC.DecryptPKCS7: Invalid content
The code performs two tests, the first test is done by directly calling functions:
EASstreamCrypt / EASstreamDecrypt
a second test calls a very simple wrappers:
streamCryptWrapper / streamDecryptWrapper
procedure streamCryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
EASstreamCrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
...and I get exception, but I don't understand why
I was looking for a problem a few hours, please help me. Thanks.
Last edited by jaclas (2016-08-05 11:20:00)
Offline
And nothing? Nobody helps me out? Please check my code :-(
Offline
I add some comments:
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes,
SynCrypto;
//helper function to convert ansi string to TBytes
function convertSB (const arg: AnsiString): TBytes;
var
i: integer;
begin
Setlength(Result, Length(arg));
for i := 0 to length(arg) - 1 do
begin
result[i] := ord (arg [i + 1]);
end;
end;
//function to encrypt aInStream used aPassword and aAESClass, result is saved to aOutStream
function AESstreamCrypt(aAESClass: TAESAbstractClass; const aInStream, aOutStream: TStream; const aPassword: TBytes): Integer;
var
aKeySize: Integer;
lAES : TAESAbstract;
lBytesIn : TBytes;
lBytesOut : TBytes;
begin
//get AES key size
aKeySize := Length(aPassword) shl 3;
//create an AES class object to encrypt stream
lAES := aAESClass.Create(aPassword, aKeySize);
try
//copy aInStream to TBytes local variable
SetLength(lBytesIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lBytesIn[0], aInStream.Size);
//encrypt TBytes
lBytesOut := lAES.EncryptPKCS7(lBytesIn, True);
Result := Length(lBytesOut);
//copy encrypted TBytes to aOutStream
aOutStream.Write(lBytesOut[0], Length(lBytesOut));
finally
lAES.Free;
end;
end;
//function to decrypt aInStream used aPassword and aEASClass, result is saved to aOutStream
function AESstreamDecrypt(aAESClass: TAESAbstractClass; aInStream, aOutStream: TStream; const aPassword: TBytes):
Integer;
var
aKeySize: Integer;
lAES : TAESAbstract;
lBytesIn : TBytes;
lBytesOut : TBytes;
begin
//get AES key size
aKeySize := Length(aPassword) shl 3;
//create AES class object to decrypt stream
lAES := aAESClass.Create(aPassword, aKeySize);
try
//copy aInStream to TBytes local variable
SetLength(lBytesIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lBytesIn[0], aInStream.Size);
//decrypt TBytes
lBytesOut := lAES.DecryptPKCS7(lBytesIn, True);
Result := Length(lBytesOut);
//copy decrypted TBytes to aOutStream
aOutStream.Write(lBytesOut[0], Length(lBytesOut));
finally
lAES.Free;
end;
end;
//simple wrapper for AESstreamCrypt function
procedure streamCryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
AESstreamCrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
//simple wrapper for AESstreamDecrypt function
procedure streamDecryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
AESstreamDecrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
//test direct crypt and wrapped crypt
procedure SelfTest;
var
decodedString: String;
inputString: string;
InStr, OutStr : TMemoryStream;
InputStringStream : TStringStream;
lInStrStream, lOutStrStream : TStringStream;
lPasswordBytes: TBytes;
begin
inputString := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque hendrerit augue quis lacus efficitur,' +
' sollicitudin tempor sapien dapibus. Vivamus quis neque congue, imperdiet nisi nec, hendrerit nulla.' +
' Ut quis dolor eget sapien sodales faucibus vel at turpis. Aenean sed varius arcu.';
lPasswordBytes := convertSB('01234567890123456789012345678901');
InStr := TMemoryStream.Create;
OutStr := TMemoryStream.Create;
InputStringStream := TStringStream.Create(inputString, TEncoding.Unicode);
try
// -------------------------------------------------------------------------
// TEST 1 - use direct AESstreamCrypt and AESstreamDecrypt functions
InStr.Clear;
OutStr.Clear;
InStr.CopyFrom(InputStringStream, 0);
InStr.Position := 0;
// crypt
AESstreamCrypt(TAESCBC, InStr, OutStr, lPasswordBytes);
//decrypt
InStr.Clear;
AESstreamDecrypt(TAESCBC, OutStr, InStr, lPasswordBytes);
decodedString := 'empty';
decodedString := Copy(PChar(InStr.Memory), 1, Length(inputString));
Assert(decodedString = inputString);
// TEST 1 PASSED
// -------------------------------------------------------------------------
// TEST 2 with wrappers streamCryptWrapper and streamDecryptWrapper
InStr.Clear;
OutStr.Clear;
InStr.CopyFrom(InputStringStream, 0);
InStr.Position := 0;
// crypt
streamCryptWrapper(InStr, OutStr, lPasswordBytes);
InStr.Clear;
// decrypt
streamDecryptWrapper(OutStr, InStr, lPasswordBytes); // <--- ESynCrypto exception: TAESCBC.DecryptPKCS7: Invalid content
decodedString := 'pustka';
InStr.Position := 0;
decodedString := Copy(PChar(InStr.Memory), 1, Length(inputString));
Assert(decodedString = inputString);
finally
InStr.Free;
OutStr.Free;
InputStringStream.Free;
end;
end;
begin
try
SelfTest;
except
on E: ESynCrypto do
Writeln('ESynCrypto: ', E.Message);
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Last edited by jaclas (2016-08-05 22:24:37)
Offline
FixInsight show warnings on SynCrypto, maybe unimportant, but...
[FixInsight Warning] SynCrypto.pas(6734): W517 Variable 'iv' hides a class field, method or property
[FixInsight Warning] SynCrypto.pas(6770): W517 Variable 'iv' hides a class field, method or property
[FixInsight Warning] SynCrypto.pas(6784): W517 Variable 'iv' hides a class field, method or property
[FixInsight Warning] SynCrypto.pas(5062): W521 Return value of function 'TAESFull.EncodeDecode' might be undefined
Offline
Included fixes for FixInsight.
See http://synopse.info/fossil/info/38757df690
Those were not armful at all, but better to get rid of them.
Offline
And again, I refactored and simplified example code, please look...
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes,
SynCrypto;
const
//string to encrypting
CInputString : string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque hendrerit augue quis lacus efficitur,' +
' sollicitudin tempor sapien dapibus. Vivamus quis neque congue, imperdiet nisi nec, hendrerit nulla.' +
' Ut quis dolor eget sapien sodales faucibus vel at turpis. Aenean sed varius arcu.';
//password
CPassword : TBytes = [0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1];
//AES initialization vector
CIV: TAESBlock = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
//function to encrypt aInStream used aPassword and aAESClass, result is saved to aOutStream
procedure AESstreamCrypt(aAESClass: TAESAbstractClass; const aInStream, aOutStream: TStream; const aPassword: TBytes);
var
aKeySize: Integer;
lAES : TAESAbstract;
lIn : RawByteString;
lOut : RawByteString;
begin
//get AES key size
aKeySize := Length(aPassword) shl 3;
//create an AES class object to encrypt stream
lAES := aAESClass.Create(aPassword, aKeySize);
try
//copy aInStream to RawByteString local variable
SetLength(lIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lIn[1], aInStream.Size);
//assign const vector
lAES.IV := CIV;
//encrypt TBytes
lOut := lAES.EncryptPKCS7(lIn, False);
//copy encrypted RawByteString to aOutStream
aOutStream.Write(lOut[1], Length(lOut));
finally
lAES.Free;
end;
end;
//function to decrypt aInStream used aPassword and aEASClass, result is saved to aOutStream
procedure AESstreamDecrypt(aAESClass: TAESAbstractClass; aInStream, aOutStream: TStream; const aPassword: TBytes);
var
aKeySize: Integer;
lAES : TAESAbstract;
lIn : RawByteString;
lOut: RawByteString;
begin
//get AES key size
aKeySize := Length(aPassword) shl 3;
//create AES class object to decrypt stream
lAES := aAESClass.Create(aPassword, aKeySize);
try
//copy aInStream to RawByteString local variable
SetLength(lIn, aInStream.Size);
aInStream.Position := 0;
aInStream.ReadBuffer(lIn[1], aInStream.Size);
//assign const vector
lAES.IV := CIV;
//decrypt TBytes
lOut := lAES.DecryptPKCS7(lIn, False);
//copy decrypted RawByteString to aOutStream
aOutStream.Write(lOut[1], Length(lOut));
finally
lAES.Free;
end;
end;
//simple wrapper on crypt method which only passes arguments to crypt method
procedure streamCryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
AESstreamCrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
//simple wrapper on decrypt method which only passes arguments to decrypt method
procedure streamDecryptWrapper(const aInStream, aOutStream: TStream; const aPassword: TBytes);
begin
AESstreamDecrypt(TAESCBC, aInStream, aOutStream, aPassword);
end;
procedure SelfTest;
var
decodedString: String;
InStr, OutStr : TStringStream;
begin
InStr := TStringStream.Create;
OutStr := TStringStream.Create;
try
// TEST 1 ------------------------------------------------------------------
InStr.Clear;
OutStr.Clear;
//put string into stream
InStr.WriteString(CInputString);
// crypt stream InStr -> OutStr
AESstreamCrypt(TAESCBC, InStr, OutStr, CPassword);
//decrypt stream OutStr -> InStr
InStr.Clear;
AESstreamDecrypt(TAESCBC, OutStr, InStr, CPassword);
//check decoded string
decodedString := InStr.DataString;
Assert(decodedString = CInputString);
// TEST 1 PASSED
// end of TEST 1 -----------------------------------------------------------
// -------------------------------------------------------------------------
// TEST 2 with simple wrapper - cause exception!
InStr.Clear;
OutStr.Clear;
//put string into stream
InStr.WriteString(CInputString);
// crypt stream InStr -> OutStr
streamCryptWrapper(InStr, OutStr, CPassword);
// decrypt stream OutStr -> InStr
InStr.Clear;
streamDecryptWrapper(OutStr, InStr, CPassword); // <--- ESynCrypto exception: TAESCBC.DecryptPKCS7: Invalid content, why??
//check decoded string
decodedString := InStr.DataString;
Assert(decodedString = CInputString);
// end of TEST 2 -----------------------------------------------------------
finally
InStr.Free;
OutStr.Free;
end;
end;
begin
try
SelfTest;
except
on E: ESynCrypto do
Writeln('ESynCrypto: ', E.Message); //TAESCBC.DecryptPKCS7: Invalid content !!!
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
...and thanks for time.
The main problem is a bug when I use wrappers, I don't know why :-(
Last edited by jaclas (2016-08-11 12:11:39)
Offline
I found error!!! Of course in my code... :-(
Offline