(17-10-2018, Saat: 12:07)seci20 Adlı Kullanıcıdan Alıntı: Merhaba ustalarım. Uzun süredir uğraştığım ama bir türlü çözüme kavuşturamadığım bir hata var. Şuanki projemi Delphi 10.2 versiyonu ile geliştiriyorum. Bir hesaplama yapmam gerekli Aes 256-ECB üzerinden yalnız bir türlü doğru hesaplamayı yapamıyorum. Aynı kodları delphi 7 üzerinden yaptığımda sorunsuz yapabiliyorum ama 10.2 versiyonunda bir türlü doğru hesaplama yapamıyorum.
Aes hesaplama için kullandığım kütüphane linki şu şekilde.
https://github.com/StephenGenusa/DCPCrypt
Hesapladığım kod ise şu şekilde.
Function StrToHex(s: ansiString;const ters:boolean=false): ansiString;
Var
i : Integer;
Begin
Result:='';
If Length(s)>0 Then
For i:=1 To Length(s) Do
begin
if ters=False then
Result:=IntToHex(Ord(s[i]),2)+Result
else
Result:=Result+IntToHex(Ord(s[i]),2);
end;
End;
function aescalcualtor (key:Ansistring):Ansistring;
var
Cipher : TDCP_rijndael;
IV : Ansistring;
Data : Ansistring;
i:integer;
Buffer : Ansistring;
begin
Data := #$00#$01#$02#$03#$04#$05#$06#$07#$08#$09#$0a#$0b#$0c#$0d#$0e#$0f;
IV := '';
Cipher := TDCP_rijndael.Create(nil);
Cipher.Init(Key[1], 256, @IV[1]);
SetLength(Buffer,16);
Cipher.EncryptECB(Data[1], Buffer[1]);
Result:=buffer;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
mmo1.Lines.Add(StrToHex(aescalcualtor('11')));
end;
Delphi 7 çıktısı ve doğru olanı
B1CD5BE4ED3DBE649DA2FD2100FB47AF
Delphi 10.2 ise şu şekilde.
527C056F6F9C657B07A1B209B38544CE
String olarak değiştirdim ansistring yaptım malasef bir türlü doğru hesaplama yaptıramıyorum. Doğru olanı delphi 7 hesaplıyor ama 10.2 malasef doğru hesaplama yapmıyor. Yardımlarınız için şimdiden çok teşekkür ederim. Doğru bir hesaplama yapan farklı bir kütüphane var ise elinizde fikirlerinizi belirtirseniz çok memnun olurum şimdiden...
ÇÖZÜM 1:
Bu makaledeki kodu deneyebilirsiniz.
https://www.delphican.com/showthread.php?tid=1987
ÇÖZÜM 2:
Ayrıca doğrudan Windows DLL lerini kullanan aşağıdaki Unit'i deneyebilirsiniz.
unit XECryptoUtils;
// XE8 Compatibility
// http://www.cnblogs.com/cb168/p/4678901.html
interface
function AES128_Encrypt(Value, Password: string): string;
function AES128_Decrypt(Value, Password: string): string;
function DecryptStringHex(ASourceStr: String; AKeyStr: String): String;
function EncryptStringHex(ASourceStr: String; AKeyStr: String): String;
implementation
uses
SysUtils,
Windows,
IdCoderMIME
{$IF CompilerVersion >= 29.0}
, IdGlobal
{$IFEND}
;
//-------------------------------------------------------------------------------------------------------------------------
// Base64 Encode/Decode
//-------------------------------------------------------------------------------------------------------------------------
{$IF CompilerVersion >= 29.0}
function Base64_Encode(Value: TIdBytes): string;
{$ELSE}
function Base64_Encode(Value: TBytes): string;
{$IFEND}
var
Encoder: TIdEncoderMIME;
begin
Encoder := TIdEncoderMIME.Create(nil);
try
Result := Encoder.EncodeBytes(Value);
finally
Encoder.Free;
end;
end;
{$IF CompilerVersion >= 29.0}
function Base64_Decode(Value: string): TIdBytes;
{$ELSE}
function Base64_Decode(Value: string): TBytes;
{$IFEND}
var
Encoder: TIdDecoderMIME;
begin
Encoder := TIdDecoderMIME.Create(nil);
try
Result := Encoder.DecodeBytes(Value);
finally
Encoder.Free;
end;
end;
//-------------------------------------------------------------------------------------------------------------------------
// WinCrypt.h
//-------------------------------------------------------------------------------------------------------------------------
type
HCRYPTPROV = Cardinal;
HCRYPTKEY = Cardinal;
ALG_ID = Cardinal;
HCRYPTHASH = Cardinal;
const
_lib_ADVAPI32 = 'ADVAPI32.dll';
CALG_SHA_256 = 32780;
CALG_AES_128 = 26126;
CRYPT_NEWKEYSET = $00000008;
PROV_RSA_AES = 24;
KP_MODE = 4;
CRYPT_MODE_CBC = 1;
function CryptAcquireContext(var Prov: HCRYPTPROV; Container: PChar; Provider: PChar; ProvType: LongWord; Flags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptAcquireContextW';
function CryptDeriveKey(Prov: HCRYPTPROV; Algid: ALG_ID; BaseData: HCRYPTHASH; Flags: LongWord; var Key: HCRYPTKEY): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDeriveKey';
function CryptSetKeyParam(hKey: HCRYPTKEY; dwParam: LongInt; pbData: PBYTE; dwFlags: LongInt): LongBool stdcall; stdcall; external _lib_ADVAPI32 name 'CryptSetKeyParam';
function CryptEncrypt(Key: HCRYPTKEY; Hash: HCRYPTHASH; Final: LongBool; Flags: LongWord; pbData: PBYTE; var Len: LongInt; BufLen: LongInt): LongBool;stdcall;external _lib_ADVAPI32 name 'CryptEncrypt';
function CryptDecrypt(Key: HCRYPTKEY; Hash: HCRYPTHASH; Final: LongBool; Flags: LongWord; pbData: PBYTE; var Len: LongInt): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDecrypt';
function CryptCreateHash(Prov: HCRYPTPROV; Algid: ALG_ID; Key: HCRYPTKEY; Flags: LongWord; var Hash: HCRYPTHASH): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptCreateHash';
function CryptHashData(Hash: HCRYPTHASH; Data: PChar; DataLen: LongWord; Flags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptHashData';
function CryptReleaseContext(hProv: HCRYPTPROV; dwFlags: LongWord): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptReleaseContext';
function CryptDestroyHash(hHash: HCRYPTHASH): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDestroyHash';
function CryptDestroyKey(hKey: HCRYPTKEY): LongBool; stdcall; external _lib_ADVAPI32 name 'CryptDestroyKey';
//-------------------------------------------------------------------------------------------------------------------------
{$WARN SYMBOL_PLATFORM OFF}
function __CryptAcquireContext(ProviderType: Integer): HCRYPTPROV;
begin
if (not CryptAcquireContext(Result, nil, nil, ProviderType, 0)) then
begin
if HRESULT(GetLastError) = NTE_BAD_KEYSET then
Win32Check(CryptAcquireContext(Result, nil, nil, ProviderType, CRYPT_NEWKEYSET))
else
RaiseLastOSError;
end;
end;
function __AES128_DeriveKeyFromPassword(m_hProv: HCRYPTPROV; Password: string): HCRYPTKEY;
var
hHash: HCRYPTHASH;
Mode: DWORD;
begin
Win32Check(CryptCreateHash(m_hProv, CALG_SHA_256, 0, 0, hHash));
try
Win32Check(CryptHashData(hHash, PChar(Password), Length(Password) * SizeOf(Char), 0));
Win32Check(CryptDeriveKey(m_hProv, CALG_AES_128, hHash, 0, Result));
// Wine uses a different default mode of CRYPT_MODE_EBC
Mode := CRYPT_MODE_CBC;
Win32Check(CryptSetKeyParam(Result, KP_MODE, Pointer(@Mode), 0));
finally
CryptDestroyHash(hHash);
end;
end;
function AES128_Encrypt(Value, Password: string): string;
var
hCProv: HCRYPTPROV;
hKey: HCRYPTKEY;
lul_datalen: Integer;
lul_buflen: Integer;
{$IF CompilerVersion >= 29.0}
Buffer: TIdBytes;
ABuffer : TBytes;
{$ELSE}
Buffer: TBytes;
{$IFEND}
begin
Assert(Password <> '');
if (Value = '') then
Result := ''
else
begin
hCProv := __CryptAcquireContext(PROV_RSA_AES);
try
hKey := __AES128_DeriveKeyFromPassword(hCProv, Password);
try
// allocate buffer space
lul_datalen := Length(Value) * SizeOf(Char);
{$IF CompilerVersion >= 29.0}
ABuffer := TEncoding.Unicode.GetBytes(Value + ' ');
Buffer := RawToBytes(ABuffer[0], Length(ABuffer));
{$ELSE}
Buffer := TEncoding.Unicode.GetBytes(Value + ' ');
{$IFEND}
lul_buflen := Length(Buffer);
// encrypt to buffer
Win32Check(CryptEncrypt(hKey, 0, True, 0, @Buffer[0], lul_datalen, lul_buflen));
SetLength(Buffer, lul_datalen);
// base 64 result
Result := Base64_Encode(Buffer);
finally
CryptDestroyKey(hKey);
end;
finally
CryptReleaseContext(hCProv, 0);
end;
end;
end;
function AES128_Decrypt(Value, Password: string): string;
var
hCProv: HCRYPTPROV;
hKey: HCRYPTKEY;
lul_datalen: Integer;
{$IF CompilerVersion >= 29.0}
Buffer: TIdBytes;
ABuffer : TBytes;
{$ELSE}
Buffer: TBytes;
{$IFEND}
begin
Assert(Password <> '');
if Value = '' then
Result := ''
else
begin
hCProv := __CryptAcquireContext(PROV_RSA_AES);
try
hKey := __AES128_DeriveKeyFromPassword(hCProv, Password);
try
// decode base64
Buffer := Base64_Decode(Value);
// allocate buffer space
lul_datalen := Length(Buffer);
// decrypt buffer to to string
Win32Check(CryptDecrypt(hKey, 0, True, 0, @Buffer[0], lul_datalen));
{$IF CompilerVersion >= 29.0}
SetLength(ABuffer, lul_datalen);
BytesToRaw(Buffer, ABuffer[0], lul_datalen);
Result := TEncoding.Unicode.GetString(ABuffer, 0, lul_datalen);
{$ELSE}
Result := TEncoding.Unicode.GetString(Buffer, 0, lul_datalen);
{$IFEND}
finally
CryptDestroyKey(hKey);
end;
finally
CryptReleaseContext(hCProv, 0);
end;
end;
end;
function StringToHex(S: string): string;
var
i: integer;
begin
Result := '';
// Go throught every single characters, and convert them
// to hexadecimal...
for i := 1 to Length( S ) do
Result := Result + IntToHex( Ord( S[i] ), 2 );
end;
function HexToString(S: string): string;
var
i: integer;
begin
Result := '';
// Go throught every single hexadecimal characters, and convert
// them to ASCII characters...
for i := 1 to Length( S ) do
begin
// Only process chunk of 2 digit Hexadecimal...
if ((i mod 2) = 1) then
Result := Result + Chr( StrToInt( '0x' + Copy( S, i, 2 )));
end;
end;
function EncryptStringHex(ASourceStr: String; AKeyStr: String): String;
begin
Result := AES128_Encrypt(ASourceStr, AKeyStr);
Result := StringToHex(Result);
end;
function DecryptStringHex(ASourceStr: String; AKeyStr: String): String;
begin
Result := AES128_Decrypt(HexToString(ASourceStr), AKeyStr);
end;
end.