Skip to content

Commit 9821500

Browse files
- Correção de Bug na Cripto AES (Nativa do RAL)
- Implementação de Cripto usando OpenSSL
1 parent 37ded8a commit 9821500

File tree

8 files changed

+499
-33
lines changed

8 files changed

+499
-33
lines changed

src/base/RALTypes.pas

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ function RALHighStr(const AStr: StringRAL): integer;
8888
function StringToBytesUTF8(const AString: StringRAL): TBytes;
8989
function BytesToStringUTF8(const ABytes: TBytes): StringRAL;
9090

91+
function StringToBytes(const AString: StringRAL): TBytes;
92+
function BytesToString(const ABytes: TBytes): StringRAL;
93+
9194
{$IF NOT Defined(FPC) AND NOT Defined(DELPHIXE6UP)}
9295
function DateToISO8601(const AValue: TDateTime): StringRAL;
9396
function ISO8601ToDate(const AValue: StringRAL): TDateTime;
@@ -107,6 +110,21 @@ function RALHighStr(const AStr: StringRAL): integer;
107110
{$IFEND}
108111
end;
109112

113+
function StringToBytes(const AString: StringRAL): TBytes;
114+
{$IFNDEF HAS_Encoding}
115+
var
116+
vStr : ansistring;
117+
{$ENDIF}
118+
begin
119+
{$IFDEF HAS_Encoding}
120+
Result := TEncoding.ANSI.GetBytes(AString);
121+
{$ELSE}
122+
vStr := AString;
123+
SetLength(Result, Length(vStr));
124+
Move(vStr[POSINISTR], Result[0], Length(vStr));
125+
{$ENDIF}
126+
end;
127+
110128
function StringToBytesUTF8(const AString: StringRAL): TBytes;
111129
{$IFNDEF HAS_Encoding}
112130
var
@@ -122,6 +140,21 @@ function StringToBytesUTF8(const AString: StringRAL): TBytes;
122140
{$ENDIF}
123141
end;
124142

143+
function BytesToString(const ABytes: TBytes): StringRAL;
144+
{$IFNDEF HAS_Encoding}
145+
var
146+
vStr : ansistring;
147+
{$ENDIF}
148+
begin
149+
{$IFDEF HAS_Encoding}
150+
Result := TEncoding.ANSI.GetString(ABytes);
151+
{$ELSE}
152+
SetLength(vStr, Length(ABytes));
153+
Move(ABytes[0], vStr[POSINISTR], Length(ABytes));
154+
Result := UTF8Decode(vStr);
155+
{$ENDIF}
156+
end;
157+
125158
function BytesToStringUTF8(const ABytes: TBytes): StringRAL;
126159
{$IFNDEF HAS_Encoding}
127160
var

src/utils/RALBase64.pas

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ TRALBase64 = class
2424
class function DecodeAsBytes(AValue: TStream): TBytes; overload;
2525
class function DecodeAsStream(AValue: TStream): TStream; overload;
2626
class function DecodeAsStream(AValue: StringRAL): TStream; overload;
27-
class function Encode(const AValue: StringRAL): StringRAL; overload;
27+
class function Encode(const AValue: StringRAL; ABinary : boolean = false): StringRAL; overload;
2828
class function Encode(AValue: TBytes): StringRAL; overload;
2929
class function Encode(AValue: TStream): StringRAL; overload;
3030
class function EncodeAsBytes(const AValue: StringRAL): TBytes; overload;
@@ -72,7 +72,7 @@ class function TRALBase64.Decode(const AValue: StringRAL): StringRAL;
7272
vStream: TStream;
7373
begin
7474
if AValue = '' then
75-
Raise Exception.Create(emHMACEmptyText);
75+
raise Exception.Create(emHMACEmptyText);
7676

7777
vStream := StringToStreamUTF8(AValue);
7878
try
@@ -158,7 +158,7 @@ class function TRALBase64.DecodeAsStream(AValue: StringRAL): TStream;
158158
var
159159
vStream: TStream;
160160
begin
161-
vStream := StringToStreamUTF8(AValue);
161+
vStream := StringToStream(AValue);
162162
try
163163
Result := DecodeAsStream(vStream);
164164
finally
@@ -195,7 +195,7 @@ class function TRALBase64.DecodeAsBytes(const AValue: StringRAL): TBytes;
195195
var
196196
vStream: TStream;
197197
begin
198-
vStream := StringToStreamUTF8(AValue);
198+
vStream := StringToStream(AValue);
199199
try
200200
Result := DecodeAsBytes(vStream);
201201
finally
@@ -339,14 +339,18 @@ class function TRALBase64.DecodeBase64(AInput, AOutput: PByte;
339339
end;
340340
end;
341341

342-
class function TRALBase64.Encode(const AValue: StringRAL): StringRAL;
342+
class function TRALBase64.Encode(const AValue: StringRAL; ABinary : boolean): StringRAL;
343343
var
344344
vStream: TStream;
345345
begin
346346
if AValue = '' then
347-
Raise Exception.Create(emHMACEmptyText);
347+
raise Exception.Create(emHMACEmptyText);
348+
349+
if ABinary then
350+
vStream := StringToStream(AValue)
351+
else
352+
vStream := StringToStreamUTF8(AValue);
348353

349-
vStream := StringToStreamUTF8(AValue);
350354
try
351355
Result := Encode(vStream);
352356
finally

src/utils/RALCripto.pas

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ TRALCripto = class
3232
protected
3333
procedure SetKey(const AValue: StringRAL); virtual;
3434
public
35-
function Decrypt(const AValue: StringRAL): StringRAL; overload;
35+
function Decrypt(const AValue: StringRAL; ABinary : boolean = false): StringRAL; overload;
3636
function Decrypt(AValue: TBytes): StringRAL; overload;
3737
function Decrypt(AValue: TStream): StringRAL; overload;
3838
function DecryptAsBytes(const AValue: StringRAL): TBytes; overload;
3939
function DecryptAsBytes(AValue: TBytes): TBytes; overload;
4040
function DecryptAsBytes(AValue: TStream): TBytes; overload;
4141
function DecryptAsStream(AValue: TStream): TStream; virtual; abstract;
42-
function Encrypt(const AValue: StringRAL): StringRAL; overload;
42+
function Encrypt(const AValue: StringRAL; ABinary : boolean = false): StringRAL; overload;
4343
function Encrypt(AValue: TBytes): StringRAL; overload;
4444
function Encrypt(AValue: TStream): StringRAL; overload;
4545
function EncryptAsBytes(const AValue: StringRAL): TBytes; overload;
@@ -71,12 +71,20 @@ procedure TRALCripto.SetKey(const AValue: StringRAL);
7171
FKey := AValue;
7272
end;
7373

74-
function TRALCripto.Encrypt(const AValue: StringRAL): StringRAL;
74+
function TRALCripto.Encrypt(const AValue: StringRAL; ABinary : boolean): StringRAL;
7575
var
7676
vInputStream: TStringStream;
7777
begin
78+
<<<<<<< HEAD
79+
if ABinary then
80+
vStream := StringToStream(AValue)
81+
else
82+
vStream := StringToStreamUTF8(AValue);
83+
84+
=======
7885
{ TODO -cCompatibilidade : Melhorar esse código pra compatibilizar com versões antigas do Delphi }
7986
vInputStream := nil;
87+
>>>>>>> 37ded8a62a3bb2216bf3ebab8873cede96fc7d8d
8088
try
8189
vInputStream := TStringStream.Create(AValue, TEncoding.UTF8);
8290
vInputStream.Position := 0;
@@ -86,15 +94,23 @@ function TRALCripto.Encrypt(const AValue: StringRAL): StringRAL;
8694
end;
8795
end;
8896

89-
function TRALCripto.Decrypt(const AValue: StringRAL): StringRAL;
97+
function TRALCripto.Decrypt(const AValue: StringRAL; ABinary : boolean): StringRAL;
9098
var
9199
vInputStream: TStringStream;
92100
begin
101+
<<<<<<< HEAD
102+
if ABinary then
103+
vStream := StringToStream(AValue)
104+
else
105+
vStream := StringToStreamUTF8(AValue);
106+
107+
=======
93108
{ TODO -cCompatibilidade : Melhorar esse código pra compatibilizar com versões antigas do Delphi }
94109
if AValue = '' then
95110
Raise Exception.Create(emHMACEmptyText);
96111

97112
vInputStream := nil;
113+
>>>>>>> 37ded8a62a3bb2216bf3ebab8873cede96fc7d8d
98114
try
99115
{$IFDEF FPC}
100116
vInputStream := TStringStream.Create(TRALBase64.Decode(AValue), TEncoding.UTF8);

src/utils/RALCriptoAES.pas

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
<<<<<<< HEAD
2+
/// Unit for AES Criptography functions
3+
/// AES EBC (Sem IV)
4+
=======
15
/// Unit for AES Criptography functions
6+
>>>>>>> 37ded8a62a3bb2216bf3ebab8873cede96fc7d8d
27
unit RALCriptoAES;
38

49
{$I ..\base\PascalRAL.inc}
@@ -631,16 +636,15 @@ procedure TRALCriptoAES.KeyExpansion;
631636
vNb := cBlockSize;
632637
vNr := cNumberRounds[FAESType];
633638

634-
SetLength(vKey, 4 * vNk);
635-
FillChar(vKey[0], 4 * vNk, 0);
636-
SetLength(FWordKeys, vNb * (vNr + 1));
639+
vKey := StringToBytesUTF8(Key);
637640

638641
vInt := 4 * vNk;
639642
if Length(Key) < vInt then
640643
vInt := Length(Key);
641644

642-
if Length(Key) > 0 then
643-
Move(Key[PosIniStr], vKey[0], vInt);
645+
SetLength(vKey, 4 * vNk);
646+
FillChar(vKey[vInt], (4 * vNk) - vInt, 0);
647+
SetLength(FWordKeys, vNb * (vNr + 1));
644648

645649
for vInt := 0 to Pred(vNk) do
646650
FWordKeys[vInt] := PCardinal(@vKey[4 * vInt])^;
@@ -681,6 +685,7 @@ function TRALCriptoAES.EncryptAsStream(AValue: TStream): TStream;
681685
begin
682686
if not CheckKey then
683687
Exit;
688+
684689
vPadding := 0;
685690
AValue.Position := 0;
686691
vPosition := 0;

src/utils/RALCriptoOpenSSL.pas

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
unit RALCriptoOpenSSL;
2+
3+
{$I ..\base\PascalRAL.inc}
4+
5+
interface
6+
7+
uses
8+
Classes, SysUtils,
9+
RALCripto, RALTypes, RALConsts, RALTools, RALOpenSSL;
10+
11+
type
12+
TRALCriptoOpenSSLTypes = (cotAES128_CBC, cotAES192_CBC, cotAES256_CBC,
13+
cotAES128_ECB, cotAES192_ECB, cotAES256_ECB);
14+
15+
TRALCriptoOpenSSL = class(TRALCripto)
16+
private
17+
FAESType : TRALCriptoOpenSSLTypes;
18+
FIV : StringRAL;
19+
public
20+
constructor Create;
21+
22+
function DecryptAsStream(AValue: TStream): TStream; override;
23+
function EncryptAsStream(AValue: TStream): TStream; override;
24+
published
25+
property IV: StringRAL read FIV write FIV;
26+
property AESType: TRALCriptoOpenSSLTypes read FAESType write FAESType;
27+
end;
28+
29+
implementation
30+
31+
{ TRALCriptoOpenSSL }
32+
33+
constructor TRALCriptoOpenSSL.Create;
34+
begin
35+
inherited;
36+
TRALOpenSSL.GetInstance;
37+
end;
38+
39+
function TRALCriptoOpenSSL.DecryptAsStream(AValue: TStream): TStream;
40+
var
41+
vCTX: PEVP_CIPHER_CTX;
42+
vCipher, vPIV : Pointer;
43+
vBytesRead, vBytesWrite: IntegerRAL;
44+
vInBuf, vOutBuf, vKey, vIV: TBytes;
45+
vSizeBuf : Int64RAL;
46+
begin
47+
vCTX := EVP_CIPHER_CTX_new;
48+
try
49+
vKey := StringToBytesUTF8(Key);
50+
vIV := StringToBytesUTF8(FIV);
51+
52+
case FAESType of
53+
cotAES128_CBC: vCipher := EVP_aes_128_cbc;
54+
cotAES192_CBC: vCipher := EVP_aes_192_cbc;
55+
cotAES256_CBC: vCipher := EVP_aes_256_cbc;
56+
57+
cotAES128_ECB: vCipher := EVP_aes_128_ecb;
58+
cotAES192_ECB: vCipher := EVP_aes_192_ecb;
59+
cotAES256_ECB: vCipher := EVP_aes_256_ecb;
60+
end;
61+
62+
if Length(vIV) > 0 then
63+
vPIV := @vIV[0]
64+
else
65+
vPIV := nil;
66+
67+
if EVP_DecryptInit_ex(vCTX, vCipher, nil, @vKey[0], vPIV) <> 1 then
68+
raise Exception.Create('DecryptInit falhou');
69+
70+
Result := TMemoryStream.Create;
71+
Result.Size := AValue.Size;
72+
73+
AValue.Position := 0;
74+
75+
vSizeBuf := AValue.Size;
76+
if vSizeBuf > DEFAULTBUFFERSTREAMSIZE then
77+
vSizeBuf := (DEFAULTBUFFERSTREAMSIZE div 16) * 16;
78+
79+
SetLength(vInBuf, vSizeBuf);
80+
SetLength(vOutBuf, vSizeBuf);
81+
82+
while AValue.Position < AValue.Size do begin
83+
vBytesRead := AValue.Read(vInBuf[0], Length(vInBuf));
84+
85+
vBytesWrite := Length(vOutBuf);
86+
if EVP_DecryptUpdate(vCTX, @vOutBuf[0], @vBytesWrite, @vInBuf[0], vBytesRead) = 1 then
87+
Result.Write(vOutBuf[0], vBytesWrite)
88+
else
89+
raise Exception.Create('DecryptUpdate falhou');
90+
end;
91+
92+
vBytesWrite := Length(vOutBuf);
93+
if EVP_DecryptFinal_ex(vCTX, @vOutBuf[0], @vBytesWrite) = 1 then
94+
Result.Write(vOutBuf[0], vBytesWrite)
95+
else
96+
raise Exception.Create('DecryptFinal falhou');
97+
98+
Result.Size := Result.Position;
99+
Result.Position := 0;
100+
finally
101+
EVP_CIPHER_CTX_free(vCTX);
102+
end;
103+
end;
104+
105+
function TRALCriptoOpenSSL.EncryptAsStream(AValue: TStream): TStream;
106+
var
107+
vCTX: PEVP_CIPHER_CTX;
108+
vCipher, vPIV : Pointer;
109+
vBytesRead, vBytesWrite: IntegerRAL;
110+
vInBuf, vOutBuf, vKey, vIV: TBytes;
111+
vSizeBuf : Int64RAL;
112+
begin
113+
vCTX := EVP_CIPHER_CTX_new;
114+
try
115+
vKey := StringToBytesUTF8(Key);
116+
vIV := StringToBytesUTF8(FIV);
117+
118+
case FAESType of
119+
cotAES128_CBC: vCipher := EVP_aes_128_cbc;
120+
cotAES192_CBC: vCipher := EVP_aes_192_cbc;
121+
cotAES256_CBC: vCipher := EVP_aes_256_cbc;
122+
123+
cotAES128_ECB: vCipher := EVP_aes_128_ecb;
124+
cotAES192_ECB: vCipher := EVP_aes_192_ecb;
125+
cotAES256_ECB: vCipher := EVP_aes_256_ecb;
126+
end;
127+
128+
if Length(vIV) > 0 then
129+
vPIV := @vIV[0]
130+
else
131+
vPIV := nil;
132+
133+
if EVP_EncryptInit_ex(vCTX, vCipher, nil, @vKey[0], vPIV) <> 1 then
134+
raise Exception.Create('EncryptInit falhou');
135+
136+
Result := TMemoryStream.Create;
137+
Result.Size := AValue.Size + 16;
138+
139+
AValue.Position := 0;
140+
141+
vSizeBuf := AValue.Size;
142+
if vSizeBuf > DEFAULTBUFFERSTREAMSIZE then
143+
vSizeBuf := (DEFAULTBUFFERSTREAMSIZE div 16) * 16;
144+
145+
SetLength(vInBuf, vSizeBuf);
146+
SetLength(vOutBuf, vSizeBuf + 16);
147+
148+
while AValue.Position < AValue.Size do begin
149+
vBytesRead := AValue.Read(vInBuf[0], Length(vInBuf));
150+
151+
vBytesWrite := Length(vOutBuf);
152+
if EVP_EncryptUpdate(vCTX, @vOutBuf[0], @vBytesWrite, @vInBuf[0], vBytesRead) = 1 then
153+
Result.Write(vOutBuf[0], vBytesWrite)
154+
else
155+
raise Exception.Create('EncryptUpdate falhou');
156+
end;
157+
158+
vBytesWrite := Length(vOutBuf);
159+
if EVP_EncryptFinal_ex(vCTX, @vOutBuf[0], @vBytesWrite) = 1 then
160+
Result.Write(vOutBuf[0], vBytesWrite)
161+
else
162+
raise Exception.Create('EncryptFinal falhou');
163+
164+
Result.Size := Result.Position;
165+
Result.Position := 0;
166+
finally
167+
EVP_CIPHER_CTX_free(vCTX);
168+
end;
169+
end;
170+
171+
end.

0 commit comments

Comments
 (0)