Forum > Packages and Libraries
Why do PHP and Lazarus use openssl_encrypt to encrypt, but get different results
bills:
Hi.
I try to encrypt a string use PHP and Lazarus respectively. Use openssl_encrypt and same KEY and IV, why the result is different?
The php version is 7.4.3nts.
Php code:
--- Code: PHP [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---<?php $DATA = "Hello World_____";$KEY = "1234567890______";$IV = "______1234567890"; function encrypt_CBC($data, $key, $iv) { $cipher = "aes-256-cbc"; $options = OPENSSL_RAW_DATA; $paddedData = openssl_encrypt($data, $cipher, $key, $options, $iv); return $paddedData;} $CBC = encrypt_CBC($DATA, $KEY, $IV); echo "KEY : ".$KEY." (".strlen($KEY).")"."<br>";echo "IV : ".$IV." (".strlen($IV).")"."<br>";echo "DATA : ".$DATA." (".strlen($DATA).")"."<br>"; $CBC = base64_encode($CBC);echo "CBC_BASE64 : ".$CBC." (".strlen($CBC).")"."<br>"; ?>
lazarus code:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project_en; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp, StrUtils, IdMultipartFormData, IdGlobal, IdCoderMIME, idCoder, IdSSLOpenSSL, IdGlobalProtocols, LazUTF8Classes, //DCPrijndael, Base64, DCPsha1, DCPsha256, DCPcrypt2, DCPrijndael, DCPbase64, base64, DCPconst, ClpEncoders, OpenSSL { you can add units after this }; function BinStr2Hex(S: AnsiString): AnsiString;var i: integer;begin Result := ''; for i := 1 to Length(S) do Result := Result + LowerCase(HexStr(Byte(S[i]), 2));end; function my_encrypt(Data: string; key, IV: string): string;var Cipher: TDCP_rijndael; DataString, encryption_key: ansistring;begin 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); DataString := Data; Cipher := TDCP_rijndael.Create(nil); Cipher.CipherMode := cmCBC; Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]); Cipher.EncryptCBC(DataString[1], DataString[1], Length(DataString)); //Result := EncodeStringBase64(DataString); Result := EncodeStringBase64(DataString); Cipher.Free;end; var Key : AnsiString; IV : AnsiString; Data : AnsiString; CBC : AnsiString;begin // Data := 'Hello World_____'; Key := '1234567890______'; IV := '______1234567890'; CBC := my_encrypt(Data, Key, IV); //writeLn('加密:'); WriteLn('KEY : ', Key , ' (', Length(Key) , ')'); WriteLn('IV : ', IV , ' (', Length(IV) , ')'); WriteLn('DATA : ', Data , ' (', Length(Data), ')'); //WriteLn('CBC : ', BinStr2Hex(CBC) , ' (', Length(CBC) , ')'); //CBC := (CBC); WriteLn('CBC_BASE64 : ', CBC , ' (', Length(CBC) , ')');end.
The php result is:
--- Code: ---KEY : 1234567890______ (16)
IV : ______1234567890 (16)
DATA : Hello World_____ (16)
CBC_BASE64 : iZ6o4g04RAztnChNd1FQf96qBsa0T2IIsg18I0HoRNU= (44)
--- End code ---
The lazarus result is:
--- Code: ---KEY : 1234567890______ (16)
IV : ______1234567890 (16)
DATA : Hello World_____ (16)
CBC_BASE64 : iZ6o4g04RAztnChNd1FQfw== (24)
--- End code ---
Zvoni:
AnsiString vs. WideString?
Is Lazarus interpreting the underscore as whitespace?
Your result is equal for this
iZ6o4g04RAztnChNd1FQf
Try just "Hello World" without underscore in both
paweld:
Because the string before encryption must end with a character from 1 to 16 depending on how many characters are needed to padding to multiples of 16.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project_en; {$mode objfpc}{$H+} uses Classes, SysUtils, DCPcrypt2, DCPrijndael, Base64; function BinStr2Hex(S: Ansistring): Ansistring; var i: Integer; begin Result := ''; for i := 1 to Length(S) do Result := Result + LowerCase(HexStr(Byte(S[i]), 2)); end; function my_encrypt(Data: String; key, IV: String): String; var Cipher: TDCP_rijndael; DataString, encryption_key: Ansistring; l, i: Integer; begin 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); l := 16 - (Length(Data) mod 16); for i := 1 to l do Data := Data + Chr(l); DataString := Data; Cipher := TDCP_rijndael.Create(nil); Cipher.CipherMode := cmCBC; Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]); Cipher.EncryptCBC(DataString[1], DataString[1], Length(DataString)); Result := EncodeStringBase64(DataString); Cipher.Free; end; var Key: Ansistring; IV: Ansistring; Data: Ansistring; CBC: Ansistring;begin Data := 'Hello World_____'; Key := '1234567890______'; IV := '______1234567890'; CBC := my_encrypt(Data, Key, IV); WriteLn('KEY : ', Key, ' (', Length(Key), ')'); WriteLn('IV : ', IV, ' (', Length(IV), ')'); WriteLn('DATA : ', Data, ' (', Length(Data), ')'); WriteLn('CBC_BASE64 : ', CBC, ' (', Length(CBC), ')'); readln;end.result:
--- Code: ---KEY : 1234567890______ (16)
IV : ______1234567890 (16)
DATA : Hello World_____ (16)
CBC_BASE64 : iZ6o4g04RAztnChNd1FQf96qBsa0T2IIsg18I0HoRNU= (44)
--- End code ---
Thaddy:
I can't help but smile, paweld. On the spot! Well done!.
Question to OP ( bills ) is of course why are you using two different libraries that do the same thing? Openssl does the same as dcpcrypt in this case. Should not be there at all.
Mixing up libraries makes mistakes in your code, especially when you do not fully understand what you are doing.
That is not bad, that is why this forum is here. Don't feel offended.
[edit] although I "offend" some people on purpose...you are not one of them.
bills:
--- Quote from: paweld on July 12, 2024, 02:54:46 pm ---Because the string before encryption must end with a character from 1 to 16 depending on how many characters are needed to padding to multiples of 16.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project_en; {$mode objfpc}{$H+} uses Classes, SysUtils, DCPcrypt2, DCPrijndael, Base64; function BinStr2Hex(S: Ansistring): Ansistring; var i: Integer; begin Result := ''; for i := 1 to Length(S) do Result := Result + LowerCase(HexStr(Byte(S[i]), 2)); end; function my_encrypt(Data: String; key, IV: String): String; var Cipher: TDCP_rijndael; DataString, encryption_key: Ansistring; l, i: Integer; begin 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); l := 16 - (Length(Data) mod 16); for i := 1 to l do Data := Data + Chr(l); DataString := Data; Cipher := TDCP_rijndael.Create(nil); Cipher.CipherMode := cmCBC; Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]); Cipher.EncryptCBC(DataString[1], DataString[1], Length(DataString)); Result := EncodeStringBase64(DataString); Cipher.Free; end; var Key: Ansistring; IV: Ansistring; Data: Ansistring; CBC: Ansistring;begin Data := 'Hello World_____'; Key := '1234567890______'; IV := '______1234567890'; CBC := my_encrypt(Data, Key, IV); WriteLn('KEY : ', Key, ' (', Length(Key), ')'); WriteLn('IV : ', IV, ' (', Length(IV), ')'); WriteLn('DATA : ', Data, ' (', Length(Data), ')'); WriteLn('CBC_BASE64 : ', CBC, ' (', Length(CBC), ')'); readln;end.result:
--- Code: ---KEY : 1234567890______ (16)
IV : ______1234567890 (16)
DATA : Hello World_____ (16)
CBC_BASE64 : iZ6o4g04RAztnChNd1FQf96qBsa0T2IIsg18I0HoRNU= (44)
--- End code ---
--- End quote ---
Thank you @paweld.
This gives exactly the same encryption result, which perfectly explains my question.
Navigation
[0] Message Index
[#] Next page