Recent

Author Topic: (SOLVED) Encrypt string with lazarus and decrypt with php  (Read 12946 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
(SOLVED) Encrypt string with lazarus and decrypt with php
« on: April 22, 2017, 05:44:17 pm »
Hi everyone, I'm trying to encrypt a string with a symmetric key algorithm (such as blowfish or aes) so decrypt it with php. But whatever I do not succeed, who tells me how to do it? The string sends it to a php page with synapse. Who gives me an example to understand? Thank you
« Last Edit: April 27, 2017, 07:48:30 pm by xinyiman »
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: Encrypt string with lazarus and decrypt with php
« Reply #1 on: April 22, 2017, 08:57:48 pm »
These types of incompatibilities are usually related to endianness, see this post: http://forum.lazarus.freepascal.org/index.php?topic=35149.0

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Encrypt string with lazarus and decrypt with php
« Reply #2 on: April 25, 2017, 02:32:01 pm »
Hi, I do not understand how to fix it even after reading the post you've reported to me. I attach an example of where I came.

The lazarus program is enough to compile it and click on the encrypt button, then just look at the php file that is already parsed as I would like.

Do you tell me where I am wrong?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Encrypt string with lazarus and decrypt with php
« Reply #3 on: April 27, 2017, 08:11:07 am »
No suggestion?
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Encrypt string with lazarus and decrypt with php
« Reply #4 on: April 27, 2017, 10:07:28 am »
No suggestion?
One thing for sure, dcpcrypt encrypted value differs from mcrypt_encrypt one, even after forcing the key and initialization vector to be of totally the same without relying on padding behavior. I haven't checked deep enough, but it could be due to differences of what data are actually encrypted in the end. Using plain array instead of string might solve the problem as string is rather an abstract concept and implemented differently in each language.

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Encrypt string with lazarus and decrypt with php
« Reply #5 on: April 27, 2017, 10:30:13 am »
No suggestion?
One thing for sure, dcpcrypt encrypted value differs from mcrypt_encrypt one, even after forcing the key and initialization vector to be of totally the same without relying on padding behavior. I haven't checked deep enough, but it could be due to differences of what data are actually encrypted in the end. Using plain array instead of string might solve the problem as string is rather an abstract concept and implemented differently in each language.

Kindly if you have time, you would modify the source I posted with what you suggested, just because there is no risk of misunderstanding your answer.

Thank you
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Encrypt string with lazarus and decrypt with php
« Reply #6 on: April 27, 2017, 02:33:16 pm »
Given:
- a key 'mysimplekey'
- a seed value '123456'
- data to be encrypted 'Hello world'
- the resulting base64 string from php 'cjdoH5GFDaj6SGo+DCV4+g=='

The following FPC code is able to produce that.
Code: Pascal  [Select][+][-]
  1. program xiny1;
  2. {$MODE OBJFPC}{$H+}
  3. uses
  4.   SysUtils, StrUtils,
  5.   DCPCrypt2,
  6.   DCPrijndael,
  7.   dcpbase64;
  8.  
  9. procedure test;
  10. var
  11.   Cipher : TDCP_rijndael;
  12.   Key    : Ansistring;
  13.   IV     : Ansistring;
  14.   Data   : Ansistring;
  15.   Data64 : AnsiString;
  16. begin
  17.   Key  := 'mysimplekey';
  18.   IV   := '123456';
  19.   Data := 'Hello world';
  20.  
  21.   // Key <= 16 so adjust
  22.   Key  := AddCharR(#0, Key  , 16);
  23.   IV   := AddCharR(#0, IV   , 16);
  24.   Data := AddCharR(#0, Data , 16);
  25.  
  26.   WriteLn('KEY  : ', key  , ' (', length(Key) , ')');
  27.   WriteLn('IV   : ', IV   , ' (', length(IV)  , ')');
  28.   WriteLn('DATA : ', data , ' (', Length(Data), ')');
  29.  
  30.   Cipher := TDCP_rijndael.Create(nil);
  31.  
  32.   // Key <= 16 so adjust
  33.   Cipher.Init(Key[1], 128, @IV[1]);
  34.   Cipher.EncryptCBC(Data[1],Data[1],Length(Data));
  35.   Cipher.Free;
  36.  
  37.   WriteLn('DATA_ENC:', Data, ' (', Length(Data), ')');
  38.   Data64 := Base64EncodeStr(Data);
  39.   WriteLn('DATA_BASE64_ENC: ', Data64, ' (', Length(Data), ')');
  40. end;
  41.  
  42. begin
  43.   test;
  44. end.
  45.  
The outputted DATA_BASE64_ENC matches your $valore value.

In case that is not what you meant, then please be more explicit in your question and/or elaborate.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: Encrypt string with lazarus and decrypt with php
« Reply #7 on: April 27, 2017, 02:57:49 pm »
You should also remember that when using CBC, the data size must be a multiple of block size (pad with zero) to be fully compatible with other implementations (eg. Python's PyCrypt) and the size of the initialization vector should always match the ciphers block size.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Encrypt string with lazarus and decrypt with php
« Reply #8 on: April 27, 2017, 03:32:59 pm »
@fungus:

Indeed  :)

Pity as TS was almost there.

The posted archive contained code that has KeySize and BlockSize declared as constants (with too high values for the chosen example) and which obviously doesn't work.

Together with your hints, TS should be able to sort this out once and for all. (please don't start yet another thread on this subject. Though, credit for your research on php side of things as most seem to stumble on hurdles right there)

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Encrypt string with lazarus and decrypt with php
« Reply #9 on: April 27, 2017, 03:54:56 pm »
Given:
- a key 'mysimplekey'
- a seed value '123456'
- data to be encrypted 'Hello world'
- the resulting base64 string from php 'cjdoH5GFDaj6SGo+DCV4+g=='

The following FPC code is able to produce that.
Code: Pascal  [Select][+][-]
  1. program xiny1;
  2. {$MODE OBJFPC}{$H+}
  3. uses
  4.   SysUtils, StrUtils,
  5.   DCPCrypt2,
  6.   DCPrijndael,
  7.   dcpbase64;
  8.  
  9. procedure test;
  10. var
  11.   Cipher : TDCP_rijndael;
  12.   Key    : Ansistring;
  13.   IV     : Ansistring;
  14.   Data   : Ansistring;
  15.   Data64 : AnsiString;
  16. begin
  17.   Key  := 'mysimplekey';
  18.   IV   := '123456';
  19.   Data := 'Hello world';
  20.  
  21.   // Key <= 16 so adjust
  22.   Key  := AddCharR(#0, Key  , 16);
  23.   IV   := AddCharR(#0, IV   , 16);
  24.   Data := AddCharR(#0, Data , 16);
  25.  
  26.   WriteLn('KEY  : ', key  , ' (', length(Key) , ')');
  27.   WriteLn('IV   : ', IV   , ' (', length(IV)  , ')');
  28.   WriteLn('DATA : ', data , ' (', Length(Data), ')');
  29.  
  30.   Cipher := TDCP_rijndael.Create(nil);
  31.  
  32.   // Key <= 16 so adjust
  33.   Cipher.Init(Key[1], 128, @IV[1]);
  34.   Cipher.EncryptCBC(Data[1],Data[1],Length(Data));
  35.   Cipher.Free;
  36.  
  37.   WriteLn('DATA_ENC:', Data, ' (', Length(Data), ')');
  38.   Data64 := Base64EncodeStr(Data);
  39.   WriteLn('DATA_BASE64_ENC: ', Data64, ' (', Length(Data), ')');
  40. end;
  41.  
  42. begin
  43.   test;
  44. end.
  45.  
The outputted DATA_BASE64_ENC matches your $valore value.

In case that is not what you meant, then please be more explicit in your question and/or elaborate.


I did not explain, I have to succeed from php to decrypt the cipher code with lazarus. If you try to run the php code you will see that the result is not 'Hello world'.

I have to php from recovering the clear string I had in the lazarus software. Now I understand if I'm wrong with something from lazarus code or php code.


EDIT:
If change the php code in this mode:

Code: PHP  [Select][+][-]
  1. <?php
  2.     $key = 'mysimplekey';
  3.     $iv = '123456';
  4.  
  5.  
  6.     $valore = base64_decode('cjdoH5GFDaj6SGo+DCV4+g==');
  7.  
  8.         echo "valore: " . $valore . "\n\r";
  9.           echo '<p>ECB Decrypted'.mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,$valore,MCRYPT_MODE_ECB,$iv)."\n\r";
  10.           echo '<p>CBC Decrypted'.mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,$valore,MCRYPT_MODE_CBC,$iv)."\n\r";
  11.        
  12. ?>
  13.  

The conversion of php is: W_XZworld

« Last Edit: April 27, 2017, 03:59:28 pm by xinyiman »
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: Encrypt string with lazarus and decrypt with php
« Reply #10 on: April 27, 2017, 04:08:32 pm »
Because AES CBC uses a 128 bit (16 byte) block size, your message must be a multiple of that. Also you must use a 128 bit IV and for good measures you should use a 128 bit passphrase (secret) for 128 bit encryption. In Lazarus please try to encrypt with the values:

Message = "Hello World_____"
Secret = "1234567890______"
IV = "______1234567890"

and try to decrypt the result in PHP with the above Secret & IV.

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Encrypt string with lazarus and decrypt with php
« Reply #11 on: April 27, 2017, 04:11:58 pm »
Ah, i see that i spoke too soon  :)

Perhaps something like this is able to help you out ?

e.g. it explains a bit more into detail what Fungus already pointed out. I'm sure there are far better websites/examples...

Also take note of SO topics like this one, which shows your not the only one (or pascal language for that matter) and that padding things the correct way is a pita.
« Last Edit: April 27, 2017, 04:26:19 pm by molly »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Encrypt string with lazarus and decrypt with php
« Reply #12 on: April 27, 2017, 04:38:49 pm »
Thank you, you are right, and you wrote it even further but I did not see it.


Thanks so much
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: Encrypt string with lazarus and decrypt with php
« Reply #13 on: April 27, 2017, 04:51:38 pm »
More horror here at php online documentation, at the comments  :)

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: (SOLVED) Encrypt string with lazarus and decrypt with php
« Reply #14 on: April 28, 2017, 12:11:54 am »
As for proof ...

Pascal version:
Code: Pascal  [Select][+][-]
  1. program plip;
  2.  
  3. {$MODE OBJFPC}{$H+}
  4.  
  5. uses
  6.   SysUtils
  7.   DCPcrypt2, DCPrijndael, DCPbase64;
  8.  
  9.  
  10. function BinStr2Hex(S: AnsiString): AnsiString;
  11. var
  12.   i: integer;
  13. begin
  14.   Result := '';
  15.   for i := 1 to Length(S)
  16.     do Result := Result + LowerCase(HexStr(Byte(S[i]), 2));
  17. end;
  18.  
  19.  
  20. var
  21.   Cipher : TDCP_rijndael;
  22.   Key    : AnsiString;
  23.   IV     : AnsiString;
  24.   Data   : AnsiString;
  25.  
  26.   CBC    : AnsiString;
  27.   ECB    : AnsiString;
  28.   Buffer : AnsiString;
  29.  
  30. begin
  31.   Data := 'Hello World_____';
  32.   Key  := '1234567890______';
  33.   IV   := '______1234567890';
  34.  
  35.   Cipher := TDCP_rijndael.Create(nil);
  36.   Cipher.Init(Key[1], 128, @IV[1]);
  37.   SetLength(Buffer, Length(Data));
  38.   Cipher.EncryptECB(Data[1], Buffer[1]);
  39.   Cipher.Free;
  40.   ECB := Buffer;  
  41.  
  42.   Cipher := TDCP_rijndael.Create(nil);
  43.   Cipher.Init(Key[1], 128, @IV[1]);
  44.   SetLength(Buffer, Length(Data));
  45.   Cipher.EncryptCBC(Data[1], Buffer[1], Length(Data));
  46.   Cipher.Free;
  47.   CBC := Buffer;
  48.  
  49.   WriteLn('KEY        : ', Key             , ' (', Length(Key) , ')');
  50.   WriteLn('IV         : ', IV              , ' (', Length(IV)  , ')');
  51.   WriteLn('DATA       : ', Data            , ' (', Length(Data), ')');
  52.   WriteLn;  
  53.   WriteLn('ECB        : ', BinStr2Hex(ECB) , ' (', Length(ECB) , ')');
  54.   WriteLn('CBC        : ', BinStr2Hex(CBC) , ' (', Length(CBC) , ')');
  55.   WriteLn;  
  56.   ECB := Base64EncodeStr(ECB);
  57.   WriteLn('ECB_BASE64 : ', ECB             , ' (', Length(ECB) , ')');
  58.   CBC := Base64EncodeStr(CBC);
  59.   WriteLn('CBC_BASE64 : ', CBC             , ' (', Length(CBC) , ')');
  60. end.
  61.  


php version:
Code: PHP  [Select][+][-]
  1. <?php
  2.  
  3.   $DATA = "Hello World_____";
  4.   $KEY  = "1234567890______";
  5.   $IV   = "______1234567890";
  6.  
  7.   $ECB = mcrypt_ecb(MCRYPT_RIJNDAEL_128,$KEY,$DATA,MCRYPT_ENCRYPT,$IV);
  8.   $CBC = mcrypt_cbc(MCRYPT_RIJNDAEL_128,$KEY,$DATA,MCRYPT_ENCRYPT,$IV);
  9.  
  10.   echo "KEY        : ".$KEY." (".strlen($KEY).")"."\n";
  11.   echo "IV         : ".$IV." (".strlen($IV).")"."\n";
  12.   echo "DATA       : ".$DATA." (".strlen($DATA).")"."\n";
  13.   echo "\n";
  14.   echo "ECB        : ".bin2hex($ECB)." (".strlen($ECB).")"."\n";
  15.   echo "CBC        : ".bin2hex($CBC)." (".strlen($CBC).")"."\n";
  16.   echo "\n";
  17.   $ECB = base64_encode($ECB);
  18.   echo "ECB_BASE64 : ".$ECB." (".strlen($ECB).")"."\n";
  19.   $CBC = base64_encode($CBC);
  20.   echo "CBC_BASE64 : ".$CBC." (".strlen($CBC).")"."\n";
  21.  
  22. ?>
  23.  
  24.  


Pascal output
Code: [Select]
KEY        : 1234567890______ (16)
IV         : ______1234567890 (16)
DATA       : Hello World_____ (16)

ECB        : aeb97e57a968e70c22bdfc335591b9c6 (16)
CBC        : 8d0d7e91e4d0cdad7a77727c96a124f5 (16)

ECB_BASE64 : rrl+V6lo5wwivfwzVZG5xg== (24)
CBC_BASE64 : jQ1+keTQza16d3J8lqEk9Q== (24)

php output
Code: [Select]
KEY        : 1234567890______ (16)
IV         : ______1234567890 (16)
DATA       : Hello World_____ (16)

ECB        : aeb97e57a968e70c22bdfc335591b9c6 (16)
CBC        : 8d0d7e91e4d0cdad7a77727c96a124f5 (16)

ECB_BASE64 : rrl+V6lo5wwivfwzVZG5xg== (24)
CBC_BASE64 : jQ1+keTQza16d3J8lqEk9Q== (24)

So, once you have a solid base then you can start thinking about messing around with data that doesn't match up the requirements, therefor needs (zero-)padding, and requires fixing up the mess that base64_encode/decode functions made out of things.

And we haven't even started actually sending/receiving data over the interwebs or hashing a key... oh, you want to use ssl as well you said ? :D

Therefor it would be recommended to build on top of what you know is working and take small steps from there to see where things might go amiss. It might perhaps sound tedious to do but that is the only way you are able to figure out where exactly things go wrong (if they go wrong) and be able to 'fix' in  case it requires fixing.

edit: php code and output matching
« Last Edit: April 28, 2017, 03:32:16 pm by molly »

 

TinyPortal © 2005-2018