Link to home
Start Free TrialLog in
Avatar of DSOM
DSOMFlag for United States of America

asked on

Delphi 2009 TP Lockbox AES_256 encryption to PHP decryption

I need to encrypt a string in Delphi and send it to a PHP script to be decoded to its original form.

So far my efforts have failed and I can't seem to find a working example.  Please help.
SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DSOM

ASKER

I write a simple routine to show how the code works:

components from TPLockbox are
TCryptographicLibrary
TCodec:
  ChainMode: CBC *
  Cipher: [AES-256 *]

procedure

procedure test;
var clear, encrypted: ansistring;
    key: string;
begin
  key:='test';
  clear:='This is a test';

  codec1.Password:=key;
  memo1.Lines.Add(clear);
  codec1.EncryptAnsiString(clear, encrypted);
  memo1.Lines.Add(encrypted);
  codec1.DecryptAnsiString(clear, encrypted);
  memo1.Lines.Add(clear);
end;

Open in new window


output
This is a test
Aop20T3+dS6Bb33B+L3p6qYFjfR7bA==
This is a test

Open in new window


No idea how to do the PHP side
greetings   DSOM, , From my experience, I will state that encryption (even using the same algorithm) on TWO DIFFERENT platforms (Delphi-PHP) may not always work, because of subtle differences in the way the algorithm was translated to the working code for that platform.  However, before I can start to do anything for this in PHP, I need specific information about how the "TP Lockbox" places the randomized IV on the encrypted "string" of it's output, I did a couple of web searches for the "TP Lockbox"  and could NOT find any info about it's operations! !
Encryption in AES  is not a simple thing, despite the few lines of code you use to encrypt in Delphi.
This lockbox thing outputs as Base 64 encode, this string - "Aop20T3+dS6Bb33B+L3p6qYFjfR7bA==" would reduce to a 22 length binary block (since you call it a string, I will also), But the AES has a fixed BLOCK size of 16 bytes, and if it uses the "usual" random IV of 16 Bytes, the output should be 32 bytes long (44 long in Base 64), If the IV is not connected to the output, it should be 16 bytes with the 14 byte input. The extra 6 bytes is a complete puzzlement to me? ?
Can you shed any knowledge on how or why the CBC is just 6 bytes longer? It wouldn't use compression would it?
I will assume that since you are calling the -
EncryptAnsiString( )
that this uses null character padding and padding removal?
Avatar of DSOM

ASKER

I know almost nothing about how TP Lockbox works.  Here is a link to the source: http://sourceforge.net/projects/tplockbox/
No luck, unfortunately.  Maybe Slick812 can help.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DSOM

ASKER

I am thinking Lockbox isn't particularly interoperable.  I am going to try dcpcrypt instead.
http://sourceforge.net/projects/lazarus-ccr/files/DCPcrypt/

If you're interested...
code for it viewable on the web:
http://sourceforge.net/p/tplockbox/code/264/tree/trunc/

downloadable:
http://sourceforge.net/projects/tplockbox/files/latest/download

Sorry for taking up your time but I appreciate you trying to help!  I am going to mark this answered.
Avatar of DSOM

ASKER

Sometimes the solution is to move on!
Thanks for the points -- sorry I couldn't find the magic.  If you have the same issues with DCPcrypt and PHP, please let us know and I'll try again.

FWIW, Here is my PHP-to-PHP encrypt/decrypt example script.

<?php // RAY_encrypt_decrypt_GET.php
error_reporting(E_ALL);

// MAN PAGE: http://php.net/manual/en/ref.mcrypt.php

class Encryption
{
    protected $key;

    public function __construct($key='quay')
    {
        // SET KEY - MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->key = $key;
    }

    public function encrypt($text)
    {
        // ENCRYPT THE DATA
        $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB);

        // MAKE IT base64() STRING SAFE FOR STORAGE AND TRANSMISSION
        return base64_encode($data);
    }

    public function decrypt($text)
    {
        // DECODE THE DATA INTO THE BINARY ENCRYPTED STRING
        $text = base64_decode($text);

        // DECRYPT THE STRING
        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB);

        // DECLOP NUL-BYTES BEFORE THE RETURN
        return trim($data);
    }
}

// INSTANTIATE AN ENCRYPTION OBJECT FROM THE CLASS
$c = new Encryption();

// INITIALIZE VARS FOR LATER USE IN THE HTML FORM
$encoded = '';
$decoded = '';

// IF ANYTHING WAS POSTED SHOW THE DATA
if (!empty($_GET["clearstring"]))
{
    $encoded = $c->encrypt($_GET["clearstring"]);
    echo "<br/>{$_GET["clearstring"]} YIELDS ENCODED ";
    var_dump($encoded);
}

if (!empty($_GET["cryptstring"]))
{
    $decoded = $c->decrypt($_GET["cryptstring"]);
    echo "<br/>{$_GET["cryptstring"]} YIELDS DECODED ";
    var_dump($decoded);
}

// CREATE THE FORM USING HEREDOC NOTATION
$form = <<<FORM
<form method="get">
<input name="clearstring" value="$decoded" />
<input type="submit" value="ENCRYPT" />
<br/>
<input name="cryptstring" value="$encoded" />
<input type="submit" value="DECRYPT" />
</form>
FORM;

echo $form;

Open in new window

Best regards, ~Ray
OK, OK, maybe not OK? ? Thanks for the links to the Pascal code for the TP lockbox.
I spent to much time going through the code for the TP lockbox, boy, that's one mixed up load of coding arrangements, and code over kill, they have so many useless classes that do almost nothing, and have many things that are UN-nessary!
But my conclusion is - that you DID NOT set this to use the CBC mode when you ran your -
codec1.EncryptAnsiString(clear, encrypted);

instead it is in 8-bit as CFB, OFB or CTR, this would explain the 22 byte output, it has a 14 byte encrypt-block (same as the Input plain length), and a 8 byte IV block pretended to to the encrypt-block.

As far as I can see, it would use a 16 byte IV with the TRUE CBC mode, and have a 16 byte  encrypt-block with a 14 byte input, just as I said it should, so the output would be 32 bytes (around 44 for base64 encode) for true CBC mode. So you may want to learn how to use the TP lockbox, you likely need to set the MODE to CBC before you call -
codec1.EncryptAnsiString(clear, encrypted);

not that you care, or know, but these OLD modes ( CFB, OFB or CTR), should never be used, they are so out of date and lack in security value, that it is a bad idea to use them.