Recent

Author Topic: Decrypt string from PHP with DCPCrypt  (Read 2456 times)

douwe_yntema

  • Newbie
  • Posts: 1
Decrypt string from PHP with DCPCrypt
« on: January 07, 2022, 04:50:57 pm »
I try to decrypt a string witch is encrypted with PHP. I am Using Lazarus, and DCPCrypt under Linux.

The PHP Code for encrypting looks like:

Code: Pascal  [Select][+][-]
  1. if(!function_exists("my_encrypt")) {
  2.         function my_encrypt($data, $key)
  3.         {
  4. // Remove the base64 encoding from our key
  5.                 $encryption_key = base64_decode($key);
  6. // Generate an initialization vector
  7.                 $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('AES-256-CBC'));
  8. // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
  9.                 $encrypted = openssl_encrypt($data, 'AES-256-CBC', $encryption_key, 0, $iv);
  10. // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
  11.                 return base64_encode($encrypted . '::' . $iv);
  12.         }
  13. }
  14.  


The $key variable is a constant and is known in Lazarus
The IV (initialisation Vektor) is concatenated after the encrypted string, separated by  ::

The encrypted string is in a mysql database and read out via ZEOS

Below the code for decryption:

Code: Pascal  [Select][+][-]
  1.   function my_decrypt(data:string; key:string) : String;
  2.   var
  3.     index, dataLength, bsize, pad: integer;
  4.     datarr : TArrayOfString;
  5.     Cipher : TDCP_rijndael;
  6.     decryptedstr : String;
  7.     DataString, encryption_key, IV : AnsiString;
  8.   begin
  9.        datarr :=  SplitString('::', DecodeStringBase64(data), 2);
  10.        encryption_key := DecodeStringBase64(key);
  11.        IV := datarr[1];
  12.        DataString := datarr[0];
  13.        Cipher := TDCP_rijndael.Create(nil);
  14.        Cipher.Init(encryption_key[1],Length(encryption_key)*8,@IV[1]);
  15.        Cipher.CipherMode:= cmCBC;
  16.  
  17.        Cipher.DecryptCBC(DataString[1],DataString[1],Length(DataString));
  18.        my_decrypt := DataString;
  19.        Cipher.Free;
  20.   end;
  21.  
  22.  

Check In Lazarus gives the right length for Decrypted string, IV and key, however the decrypted string is wrong and  not readable.

Decryption in PHP works fine.

Some having ideas?


rvk

  • Hero Member
  • *****
  • Posts: 4637
Re: Decrypt string from PHP with DCPCrypt
« Reply #1 on: January 07, 2022, 05:22:34 pm »
Like I mentioned in the other forum (repeated here for completeness sake):

How large is your key?
Is it exactly 32 characters? (32*8=256)
(And you can change Length(encryption_key)*8 in the Init to 256 because it needs to be exactly 256 bits)

Otherwise you need to pad it to exactly 32 characters.
Code: Pascal  [Select][+][-]
  1. if (Length(encryption_key) < 32) then
  2.   while Length(encryption_key) < 32 do encryption_key := encryption_key + AnsiChar(0);
  3. encryption_key := Copy(encryption_key, 1, 32); // for the instance Length(encryption_key) > 32

Thaddy

  • Hero Member
  • *****
  • Posts: 11543
Re: Decrypt string from PHP with DCPCrypt
« Reply #2 on: January 07, 2022, 08:59:50 pm »
The crypt libraries by our forum member xor-el are much better than dcpcrypt and fully conformant, which dcpcrypt is not always. dcpcrypt is good but a bit old.
xor-el's libraries have no prolems with php encrypted code to decrypt.
See https://github.com/Xor-el/CryptoLib4Pascal

That aside:
1. where is the salt?
2. the string type for dcpscript should be AnsiString in lazarus and not string, because that resolves to UTF8 under Lazarus and that is a problem..
3. you can also use the raw byte buffer routines.
4. encryption ultimately uses byte values, not string. See the importance of 2 and 3.
« Last Edit: January 07, 2022, 09:08:04 pm by Thaddy »
Путин преступник. Россияне дезинформированы.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Decrypt string from PHP with DCPCrypt
« Reply #3 on: January 07, 2022, 10:39:54 pm »
I would say use a different variable for the output:
Code: Pascal  [Select][+][-]
  1.  Cipher.DecryptCBC(DataString[1],differentVariable[1],Length(DataString))

Beside DCPCrypt and CryptoLib, you can use the same library used by PHP, OpenSSL
« Last Edit: January 07, 2022, 10:46:50 pm by engkin »

rvk

  • Hero Member
  • *****
  • Posts: 4637
Re: Decrypt string from PHP with DCPCrypt
« Reply #4 on: January 07, 2022, 11:16:36 pm »
At the moment this problem is solved.
https://www.nldelphi.com/showthread.php?43955-Decrypt-string-from-PHP-met-DCPCrypt&p=367627&viewfull=1#post367627

Because openssl_encrypt() in PHP was used without OPENSSL_RAW_DATA as option, openssl_encrypt() gives the result as a base64 encoded string. When you in turn want to use that data in DecryptCBC() you need to first base64decode it. So, together with padding the decoded key back to 32 characters, this was sufficient to make it work.
Code: Pascal  [Select][+][-]
  1. DataString := DecodeStringBase64(datarr[0]); // nu is de lengte wel goed

Complete function:
Code: Pascal  [Select][+][-]
  1. function my_decrypt(Data: string; key: string): string;
  2. var
  3.   datarr: TArrayOfString;
  4.   Cipher: TDCP_rijndael;
  5.   DataString, encryption_key, IV: ansistring;
  6. begin
  7.   datarr := SplitString('::', DecodeStringBase64(Data), 2);
  8.   encryption_key := DecodeStringBase64(key);
  9.   if (Length(encryption_key) < 32) then
  10.     while Length(encryption_key) < 32 do encryption_key := encryption_key + ansichar(0);
  11.   encryption_key := Copy(encryption_key, 1, 32);
  12.   IV := datarr[1];
  13.   DataString := DecodeStringBase64(datarr[0]); // nu is de lengte wel goed
  14.   Cipher := TDCP_rijndael.Create(nil);
  15.   Cipher.CipherMode := cmCBC;
  16.   Cipher.Init(encryption_key[1], Length(encryption_key) * 8, @IV[1]);
  17.   Cipher.DecryptCBC(DataString[1], DataString[1], Length(DataString));
  18.   my_decrypt := DataString;
  19.   Cipher.Free;
  20. end;

 

TinyPortal © 2005-2018