Als is de string weer codeer met Codebase64, dan ziet de IV er als volgt uit:
iizl86sEuDSXnKRbycqtBA==
en de encrypted string:
LzlEQVJiMUFDa2c2a1JPL3pTa1poZz09
Maar nog steeds geen goed resultaat.
Als is de string weer codeer met Codebase64, dan ziet de IV er als volgt uit:
iizl86sEuDSXnKRbycqtBA==
en de encrypted string:
LzlEQVJiMUFDa2c2a1JPL3pTa1poZz09
Maar nog steeds geen goed resultaat.
MIep: Welke code bedoel je?
Deze:
Code:function my_decrypt(data:string; key:string) : String; var index, dataLength, bsize, pad: integer; datarr : TArrayOfString; Cipher : TDCP_rijndael; decryptedstr : String; DataString, encryption_key, IV : AnsiString; begin datarr := SplitString('::', DecodeStringBase64(data), 2); encryption_key := DecodeStringBase64(key); // encryption_key := (key); if (Length(encryption_key) < 32) then while Length(encryption_key) < 32 do encryption_key := encryption_key + AnsiChar(0); encryption_key := Copy(encryption_key, 1, 32); // for the instance Length(encryption_key) > 32 // IV := datarr[1]; // DataString := datarr[0]; IV := EncodeStringBase64(datarr[1]); DataString := EncodeStringBase64(datarr[0]); writeln (DataString); Cipher := TDCP_rijndael.Create(nil); Cipher.Init(encryption_key[1],256,@IV[1]); Cipher.CipherMode:= cmCBC; Cipher.DecryptCBC(DataString[1],DataString[1],Length(DataString)); // my_decrypt := UTF8ToString(DataString); my_decrypt := (DataString); // writeln (DataString); Cipher.Free; end;
String is zeker niet leeg, 100% zeker.
Lijkt er dus op dat het bij jou ook niet werkt.
Hier een andere string:
TFhEK0FKSUgrM2VodEFoK29KK2VnRjRJbGhhbVRFbkFNWTJmdV pnSGE1dz06OkpFZkCsaCU8yyTIRhVmuQ8=
Als je deze key dan ook gebruikt in PHP dan gaat het daar toch ook al niet goed.
Want ook daar doe je een base64_decode($key) en ik weet niet wat openssl_encrypt() precies gaat doen met een key die niet lang genoeg is.
Wie heeft de key verzonnen? Is dat niet normaal ook een lange string ofzo?
De IV is wel 16 chars dus goed.
Maar de DataString is ook geen veelvoud van 16 (want die is 24).
Ik begrijp niet helemaal waarom die met == op 24 gepaded is en niet naar 32 (wat bij AES-256-CBC dacht ik wel moest of heb ik dat mis?).
Overigens kan ik je wel vertellen als je dit in PHP gebruikt je code wel werkt (OPENSSL_RAW_DATA als optie meegeven).
PHP Code:
$encrypted = openssl_encrypt($data, 'AES-256-CBC', $encryption_key, OPENSSL_RAW_DATA, $iv);
Dit gaat dan goed:
Delphi Code:
function my_decrypt(Data: string; key: string): string; var datarr: TArrayOfString; Cipher: TDCP_rijndael; DataString, encryption_key, IV: ansistring; begin datarr := SplitString('::', DecodeStringBase64(Data), 2); encryption_key := DecodeStringBase64(key); if (Length(encryption_key) < 32) then while Length(encryption_key) < 32 do encryption_key := encryption_key + ansichar(0); encryption_key := Copy(encryption_key, 1, 32); IV := datarr[1]; DataString := datarr[0]; Cipher := TDCP_rijndael.Create(nil); Cipher.CipherMode := cmCBC; while Length(DataString) mod (Cipher.BlockSize div 8) <> 0 do DataString := DataString + ansichar(0); Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]); Cipher.DecryptCBC(DataString[1], DataString[1], Length(DataString)); my_decrypt := DataString; Cipher.Free; end; var S, data, key: ansistring; begin key := 'NQ6cnIH98555I85CaZ7TVx6EZv8y4VYr'; data := '3fVJv1Tn6c6W/kTlEay01Do6IeosXzMi4DhOQNRw5YXpNg=='; S := my_decrypt(Data, key); writeln(S); end;
Resultaat: Openings balans
In mijn memo staat er echter wel een teken nog achter maar dat zal wel zo opgelost zijn.
Dus wat doet OPENSSL_RAW_DATA?
https://stackoverflow.com/questions/...sl-raw-data-do
In PHP werk het allemaal prima.
Documentatie PHP:
The passphrase. 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.
Bovenstaande gaat over de key.
Voor alle duidelijkheid:
de Key is vast: NQ6cnIH98555I85CaZ7TVx6EZv8y4VYr
de IV is achter de versleutelde string geplakt, gescheiden door ::
As Luke Park said, instead of explicitly telling openssl_encrypt to use OPENSSL_ZERO_PADDING, simply remove that option from the parameter and it will default to the PKCS #7 padding scheme (fills the rest of the block with 0x0n where n is the number of bytes necessary; + 16 0x00 if the block is already complete). Note: PKCS #5 as referenced by Luke and PKCS #7 are effectively identical in this scenario.
Deze parameter staat op 0, in PHP dus we hebben te maken met PKCS #7 padding scheme.
What is PKCS 7 padding?
PKCS #7 (Cryptographic Message Syntax) is a standard padding method that determines the number of padding bytes and then ads that as a value. For example, for a 128-bit block size, and if we have “testing”, then there are seven bytes (for ASCII coding) that represent the data, and we then have 9 (0x09) padding values.
Ik zei al dat het met OPENSSL_RAW_DATA wel werkte.
Dat betekend zonder OPENSSL_RAW_DATA dat de openssl_encrypt de data zelf al een base64 encoding meegeeft.
Als JIJ die data weer wil decrypten moet je de data wel eerst base64 decoden.
(er zit dus een dubbele encoding op)
Dus als je dit doet gaat het goed:
Delphi Code:
DataString := DecodeStringBase64(datarr[0]); // nu is de lengte wel goed
Complete code bij mij nu werkt goed:
Delphi Code:
function my_decrypt(Data: string; key: string): string; var datarr: TArrayOfString; Cipher: TDCP_rijndael; DataString, encryption_key, IV: ansistring; begin datarr := SplitString('::', DecodeStringBase64(Data), 2); encryption_key := DecodeStringBase64(key); if (Length(encryption_key) < 32) then while Length(encryption_key) < 32 do encryption_key := encryption_key + ansichar(0); encryption_key := Copy(encryption_key, 1, 32); IV := datarr[1]; DataString := DecodeStringBase64(datarr[0]); // nu is de lengte wel goed Cipher := TDCP_rijndael.Create(nil); Cipher.CipherMode := cmCBC; Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]); Cipher.DecryptCBC(DataString[1], DataString[1], Length(DataString)); my_decrypt := DataString; Cipher.Free; end; procedure TForm1.Button1Click(Sender: TObject); var S, data, key: ansistring; begin key := 'NQ6cnIH98555I85CaZ7TVx6EZv8y4VYr'; data := 'TFhEK0FKSUgrM2VodEFoK29KK2VnRjRJbGhhbVRFbkFNWTJmdVpnSGE1dz06OkpFZkCsaCU8yyTIRhVmuQ8='; S := my_decrypt(Data, key); Memo1.Lines.Add(S); end;
Resultaat: Opbrengsten december 2021
Alleen moet de data nog wel weer getrunct worden (0'en eraf) maar ik neem aan dat je dat zelf kan.
@rvk, Netjes, goed gevonden!
Ok ,mooi dat het bij jullie werkt.
Bij mij werkt het ook als is de funktie aanroep zoals
Als ik echter de data uit de database als inputstring doorgeef zoals:Code:key := 'NQ6cnIH98555I85CaZ7TVx6EZv8y4VYr'; data := 'TFhEK0FKSUgrM2VodEFoK29KK2VnRjRJbGhhbVRFbkFNWTJmdVpnSGE1dz06OkpFZkCsaCU8yyTIRhVmuQ8='; S := my_decrypt(Data, key);
Column.Field.AsString werkt het niet.
Kennelijk wordt de string corrupt o.i,d, als ik deze debug met writeln, dan lijkt alles goed.
Ik heb al andere formate geprobeer, ansistring, utf8 en widestring, en ook al met een trim er om heen, maar het blijft niet goed.
Niet goed gevonden, want bij mij werkt het niet, het programma loopt vast, door de 2 x achterelkaar DecodeStringBase64 van de inputstring. Dit is natuurlijk niet goed
Deze regel is natuurlijk niet goed:
Want dat is daarboven al gedaanCode:DataString := DecodeStringBase64(datarr[0]); // nu is de lengte wel goed
Last edited by douwe_yntema; 07-Jan-22 at 22:51.
Ok ,mooi dat het bij jullie werkt.
Bij mij werkt het ook als is de funktie aanroep zoals
Als ik echter de data uit de database als inputstring doorgeef zoals:Code:key := 'NQ6cnIH98555I85CaZ7TVx6EZv8y4VYr'; data := 'TFhEK0FKSUgrM2VodEFoK29KK2VnRjRJbGhhbVRFbkFNWTJmdVpnSGE1dz06OkpFZkCsaCU8yyTIRhVmuQ8='; S := my_decrypt(Data, key);
Column.Field.AsString werkt het niet.
Kennelijk wordt de string corrupt o.i,d, als ik deze debug met writeln, dan lijkt alles goed.
Ik heb al andere formate geprobeer, ansistring, utf8 en widestring, en ook al met een trim er om heen, maar het blijft niet goed.
Het werkt dus wel als je precies mijn code gebruikt. Er zit dus in jouw code bij de database nog iets anders mis.
En die code zien wij niet. Base64 heeft verder ook geen tekens die met UTF-8 problemen zou mogen geven.
Nee, dat is juist wel goed.
In PHP wordt de DataString die uit de openssl_encrypt komt al door die functie ZELF base64 gecodeerd. Daarna ga jij hem samen met de IV nog een keer base-encoden.
Dus zonder die OPENSSL_RAW_DATA geeft openssl_encrypt() base encoding terug.OPENSSL_RAW_DATA just tells openssl_encrypt() to return the cipherText as ... raw data. By default, it returns it Base64-encoded.
In FPC moet je echter de kale ongecodeerde Datastring meegeven. Dus die moet je eerst die kale DataString nogmaals door DecodeStringBase64 gooien voordat je DecryptCBC doet. En uit mijn code en resultaat zie je dat dat wel zou moeten werken.
Je zag dat de code wel goed is als je de strings hard erin zet. Dan moet je dus gaan vergelijken waarom dat met een TField.asString niet goed zou werken.
Last edited by rvk; 07-Jan-22 at 23:12.
Als ik de input 2x decodebase64 doe, crasht het programma. Doe ik het 1 keer, dan werkt het juist goed. Input is hard ingegeven zoals in jou voorbeeld. De parameter waar jij op doeld bij PHP doet staat en stond op raw data. Dus het is 1 keer base 64 gecodeerd en geen 2 keer zoals jij beweert. Het enig wat er tor nu toe aangepast is het padden van de key om het werkend te krijgen.
Het blijkt dus dat het decrypten wel werkt als je de inputstring hard ingeeft. Via de database werkt het echter niet, en daarom kwam ik op het verkeerde spoor.
In ieder geval bedankt voor jullie hulp en het meedenken, ik kan nu weer verder met het volgende stukje van de puzzel
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks