Link to home
Start Free TrialLog in
Avatar of JealousyPrince
JealousyPrince

asked on

Rijndael 128 bit Encryption with Delphi and PHP

Hi.

I'm sending some parameters (string) from my PC using delphi to a PHP script on my website server using the POST method.

The parameters im using should be encrypted. So my delphi program encrypts and sends the encrypted string (parameters) to my PHP script that exists on my website server, and my PHP script should decrypt the parameters. I prefer using rijndael 128 bit encryption but if there's any other encryption method it would be fine. The main point is i want my delphi to encrypt and my PHP script to decrypt the string that delphi encrypted.

I found this package: http://www.cityinthesky.co.uk/cryptography.html it has a  rijndael 128 encryption vcl component for delphi.

It also provides an example on how to encrypt using delphi and php in this link: http://www.cityinthesky.co.uk/files/PHPEncryption.zip.

However, when i test the demo they have, the encrypted string is different in the delphi app than the string in php script.
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Why not do it the easy way and use the conventionally chosen solution, HTTPS?  Writing your own encryption is a little like reinventing, if not the wheel, maybe the gearshift.  Given that all hundreds of billions of dollars of online banking transactions are able to rely on HTTPS, it should be good enough for most of our needs.

If it is useful to you, I can show you the PHP encryption technique.  Please see the code snippet for that.  Can't help with the Delphi part of this, sorry.

Best regards, ~Ray
<?php // RAY_encrypt_decrypt.php
error_reporting(E_ALL);

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

class Encryption
{
    private $eot;
    private $key;
    private $ivs;
    private $iv;

    public function __construct()
    {
        // END OF TEXT DELIMITER
        $this->eot = '___EOT';
        
        // KEY - MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->key = 'quay';
        
        // INITIALIZATION VECTOR - MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->ivs = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
        $this->iv  = mcrypt_create_iv($this->ivs);
    }

    public function Encrypt($text)
    {
        // APPEND END OF TEXT DELIMITER
        $text .= $this->eot; 
        
        // ENCRYPT THE DATA
        $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv);
        
        // MAKE IT base64() STRING SAFE FOR STORAGE AND TRANSMISSION
        $data = base64_encode($data);
        return $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, $this->iv);
        
        // REMOVE END OF TEXT DELIMITER
        $data = explode($this->eot, $data); 
        return $data[0];
    }
}

// INSTANTIATE THE CLASS
$crypt = new Encryption();

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

// IF ANYTHING WAS POSTED
if (!empty($_POST["clearstring"]))
{
    $encoded = $crypt->Encrypt($_POST["clearstring"]);
    echo "<br/>{$_POST["clearstring"]} YIELDS "; var_dump($encoded);
}

if (!empty($_POST["cryptstring"]))
{
    $decoded = $crypt->Decrypt($_POST["cryptstring"]);
    echo "<br/>{$_POST["cryptstring"]} YIELDS "; var_dump($decoded);
}

?>
<form method="post">
<input name="clearstring" value="<?=$decoded?>" />
<input type="submit" value="ENCRYPT" />
<br/>
<input name="cryptstring" value="<?=$encoded?>" />
<input type="submit" value="DECRYPT" />
</form>

Open in new window

Avatar of Marco Gasi
Hi. I had the same problem, with the same package and the same example. The strange thing is that for some period it worked fine! Suddenly, it has began to work not at all. I made sevewral trying, I alse wrote to the author, but without result. I don't know if you are intereted in, but I solved completely changing logic: I've used md5 to hash a certain string and I passed md5 hash to my php application. PHP produces its own hash for the string that it finds in a database and compares hashes. But this only works if the string to encrypt/hash can be in a database (I used this code to validate users). So, if you can use this trick depends by what you are doing.

Hope this helps. Good luck
Avatar of JealousyPrince
JealousyPrince

ASKER

The problem is that the delphi program sends the computer name and version to the php script and the php script posts the details to the database. Its something like
www.mysite.com/myscript.php and it has two parameters which are computer name and version.

I want the parameters encrypted so that whoever is using the program doesnt play with the parameters and simply change his computer name or version resulting in entering invalid data to the database. margusG Your solution isnt applicable in my case because the database is empty and is willng to accept any computer name and version. I mean i dont have any hash in my database to be compared to. My delphi program will be used by many users.
Let's step back from this a little bit... can you explain how you validate the information in the "computer name" and "version" data strings?  I am not clear how encryption helps in this case.  Please tell us a little more about the application from the "50,000 foot view" - not the technical details, just what you're trying to do, what data you need to extract and protect, etc.  Thanks.
Maybe you are interested to read this https://www.experts-exchange.com/questions/23910465/Delphi-and-PHP-I-want-to-send-a-POST-from-Delphi-to-a-PHP-script.html?sfQueryTermInfo=1+10+30+delphi+form+php
Here it seems to find a solution to pass some variables from Delphi to PHP using POST method: this way you could avoid to encrypt them because data would not appear in the url. Solution seeems to be ICS components you can find here: http://www.overbyte.be/frame_index.html?redirTo=/products/ics.html I've not tested, so I can't be more descriptive, but you could look at examples to view if truely these components allow to do such a thing.

Bye
greetings JealousyPrince, , I looked at the code in the -
http://www.cityinthesky.co.uk/files/PHPEncryption.zip
and the PHP uses some out of date (to me) encryption functions, it use 2 different "Modes" for the rijndael 128 encryption, ecb and cbc. Using a different mode will change the output encryption, and if I understand the setup of these, you MUST use the same mode for decryption. I looked at the Delphi code in uMain.pas from the zip file, and it uses the Cipher.EncryptCBC( ) function from the TDCP_rijndael. So I would guess you must use the CBC mode for the for the PHP to have reversible encryptions. I saw marqusG comment and it seemed like something must have changed in a version upgrade (version of "Delphi Cryptography Package", or Delphi version, or PHP version) so I looked at the code in the "Delphi Cryptography Package" for the rijndael 128 in the DCPrijndael.pas cipher definitions. And I could NOT find a EncryptCBC( ) function, it only has a EncryptECB( ) function in that class. I do not have time to figure this out (where the CBC mode function may be), so if I where fishing for a possible working solution, I would use the ECB mode in the delphi and php code, and I would use a KEY that is exactly the block size for the rijndael 128, that is 32 bytes. You might try and use some portion of Ray_Paseur's code in post ID:33436596, but on my servers the IVS is completely ignored in the ECB mode and this works for me -
$data = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, '66');

From using some different encryption, I would guess that the way data array blocks are padded (with 0, with spaces, etc) may be why there are differences in Delphi and PHP (maybe marqusG comment is due to padding changes from one version to another?), so you might consider doing your own block size padding in both PHP and delphi for your pre-encrypted string to have exchangeable encryption.
I'll add, , that the rijndael encryption is considered one of the more recent and more difficult, to hack out a run around. From your description, I would not think you need really good and high secure encryption. You might consider doing your own simple encryption in PHP and Delphi, with a few XOR, a few byte rotations and a couple bit shifts. It seems like you are less worried about a hacker "decrypting" your sends, but a hacker sending up a false ID.
Slick812
" It seems like you are less worried about a hacker "decrypting" your sends, but a hacker sending up a false ID." >> Thats exactly the case but im not really good in encryption programming. Can you please give me an example of how i can encode a string in delphi and decode it using php?
marqusG:
" it seems to find a solution to pass some variables from Delphi to PHP using POST method: this way you could avoid to encrypt them because data would not appear in the url" >> Thats true but any packet sniffer can still read the contents of the parameters.

Ray_Paseur:
I cant simplify it any further, the whole point is i want a delphi function to encrypt a string, and a php function to decrypt that string which was encrypted with delphi.
JealousyPrince:

We need to understand what you're protecting yourself against before we can help you.

For transport security (guarding against man in the middle attacks, etc...) Ray is correct when he says HTTPS is sufficient. Your problem appears to not be a transport encryption issue, but rather a spoof attack issue.

Correct me if I am wrong, but it appears you are trying to encrypt some strings (what it is doesn't really matter) so that people cannot sniff your traffic, see that you're putting the computer name and version in the sends, and then spoof that from other machines to either 1) circumvent copy protection or 2) destroy your database.

if that is the case, I strongly suggest that you use public and private key encryption. Research GnuPG. You'll need to generate a public key that can be distributed with your application and a private key that is held on the server. Thus, you don't have to reinvent the wheel with encryption, and can use something that is strong enough that no one in their right mind will try to decipher it.

Here are the GnuPG components for Delphi:
http://sourceforge.net/projects/gpgcomp/

Here is how to do it on the php side (you must have gpg installed on the server):
http://devzone.zend.com/article/1265

Now a further word on best practices: if you are worried about information being accidentally inserted into your database, you need to seriously consider creating sanitation routines that gaurd against SQL injections among other mal-formed data.

I can't help you with the delphi side of this, but the encryption side I know inside and out, and between Ray and I and the others, I am sure we can help you get this working.
"I cant simplify it any further"

Sure you can!  Imagine that you do not have Delphi or PHP or anything else.  Give it to us like this, "I need a way to be sure that bogus data does not pollute my data base." Or maybe, "How do I authenticate the client, to be sure only trusted individuals are sending me data?"
For my security concerns I always try to figure what a hacker would get as a reward for bypassing my encryption, if it is a password to a million dollar account I would try and use the better security (actually, I would not even try to code for that level, since real security hackers are much better than me at this sort of thing, , I would let someone else handle it), but if it is something to discourage user pranks - frustrations, and there's no money reward for bypassing, I will use some of my own code, although there are very many encryption methods for every platform, crossing platforms may have problems with the default settings in the coding.

I will offer the tested code below as a demo of what you can do, this is all PHP, but I believe if you have an fair understanding of PHP, you can translate this to pascal Delphi. Now I do not have time to even try to do a pascal version.
If you have trouble understanding the encryption functions, then this may not be a way for you, ask questions if I am unclear somewhere
<html><head><title>PHP Simple Crypt</title><style type="text/css">.rd{color:#b00;}</style></head><body BGCOLOR="#E3F7FF"><h2>Test for PHP Simple Crypt</h2>
<p>
<?php
define("VALIDBB", chr(2).chr(247).chr(15).chr(128).chr(255).chr(3));
// no ascii charaters helps for unique

//define("VALIDBB", '*k0~M-');// if you would rather use ascii text


//  NONE of the encryption methods here are up to any decent level of modern encryption
//  but can offer a mild preventive for hiding data

function aryXOR($In,$ary){$len = strlen($In);
// this uses an array of arrays with TWO values to XOR all of the text
for($a = 0; $a < count($ary); ++$a){for($i = 0; $i < $len; ++$i){
	$xor = ord($In{$i}) ^ $ary[$a][$i & 1];
	$In[$i] = chr($xor);}
	}
return $In;}

function byteRotate($In,$aryIn,$en=true){$len = strlen($In);
// this rotates the text values an the mods 256 out the result
$aryKey=array(227,79,13,162,244,31,126,65,62,250,21,3,99,211,104,111,145,222,44,81,99,203,50,100,200);// 25 count
$aryKey = array_merge($aryIn, $aryKey);
$kLen = count($aryKey);
if ($len > $kLen) for($i = $kLen; $i < $len; ++$i) $aryKey[] = $i % 256;
for($i = 0; $i < $len; ++$i){
	$xor = ord($In{$i});
	if ($en) $In[$i] = chr(($xor + $aryKey[$i]) % 256); else
	$In[$i] = chr((($xor + 256) - $aryKey[$i]) % 256);
	}
return $In;}

function shift3($In,$en=true){$len = strlen($In);
// this right shifts all text valus 3 bit position, and left shift for decrypt
$On = array();
for($i = 0; $i < $len; ++$i) $On[] = ord($In{$i});
if ($en) {$In[0] = chr((($On[0] & 31) << 3) | (($On[$len-1] & 224) >> 5));
	  for($i = 1; $i < $len; ++$i) {$In[$i] = chr((($On[$i-1] & 224) >> 5) | (($On[$i] & 31) << 3));}} else
    {$hd = ($On[1] & 7)<<5; for ($i = 1; $i < $len-1; ++$i) {$In[$i] = chr((($On[$i] & 248) >> 3) | (($On[$i+1] & 7) << 5));}
	$In[$len-1] = chr((($On[0] & 7) << 5) | (($On[$len-1] & 248) >> 3)); $In[0] = chr($hd + (($On[0] & 248)>>3));}
return $In;}

function hex2text($In){$Out='';
//$In=str_replace(' ', '', $In);
for($i=0; $i<strlen($In); $i+=2) $Out.=chr(hexdec(substr($In, $i, 2)));
return($Out);}

// // // // // // // end of functions, beginning of encrypt

$First1 = 'User Name-Version';// This is the string to be encrypted
	echo 'This is the Input, Before encryption- <b>'.$First1.'</b><br /><br />';
	/*
IMPORTANT - in my view -
	To ensure that any old falsely encrypted data will NOT be used
	I will make the first 6 bytes (characters) a special "unique" byte
	block that will identify all entry's as being valid or not.
	I use the VALIDBB defined above.
	Remember any byte block that is put in will be decrypted,
	no matter if it is valid or NOT
*/
$Test1 = VALIDBB.$First1;// add validation to beginning of Input
$ary1 = array(array(35,121),array(114,123),array(74,129),array(94,240),array(221,7));// ALL numbers are between 1 and 255
$Test1 = aryXOR($Test1,$ary1);
$ary1 = array(7,222,147,200,123,4);// ALL numbers are between 1 and 255
$Test1 = byteRotate($Test1,$ary1);
$Test1 = shift3($Test1);
$ary1 = array(array(145,36),array(14,227),array(114,239),array(184,30),array(116,231),array(99,177));
$Test1 = aryXOR($Test1,$ary1);
$ary1 = array(111,17,88);// ALL numbers are between 1 and 255
$Test1 = byteRotate($Test1,$ary1);
$ary1 = strlen($Test1);
$Test1 = substr($Test1.$Test1[0],1,$ary1);
$Test1 = shift3($Test1);

// End of Encryption

$order = array('<', '>');
$replace = array('&lt;', '&gt;');
$ary1 = str_replace($order, $replace, $Test1);
echo 'Encrypted string = '.$ary1.'<br />';

//I like to use the the HEX for web data because I can scramble the hex
$Test1 = bin2hex($Test1);
$ary1 = strlen($Test1);
$Test1 = substr($Test1.$Test1[0],1,$ary1);
// by changing One character a hex read will use the wrong pairing of hex
echo 'Encrypted HEX string used for web = '.$Test1.'<br /><br />';

// Begin Decrypt
// for WEB you should do a regex to ensure all characters are HEX
$ary1 = strlen($Test1);
$Test1 = substr($Test1[$ary1-1].$Test1,0,$ary1);
$Test1 = hex2text($Test1);
$Test1 = shift3($Test1,false);
$ary1 = strlen($Test1);
$Test1 = substr($Test1[$ary1-1].$Test1,0,$ary1);
$ary1 = array(111,17,88);
$Test1 = byteRotate($Test1,$ary1,false);

// IMPORTANT you must reverse the array order for the aryXOR function decrypt
$ary1 = array(array(99,177),array(116,231),array(184,30),array(114,239),array(14,227),array(145,36));
$Test1 = aryXOR($Test1,$ary1);
$Test1 = shift3($Test1,false);
$ary1 = array(7,222,147,200,123,4);
$Test1 = byteRotate($Test1,$ary1,false);
$ary1 = array(array(221,7),array(94,240),array(74,129),array(114,123),array(35,121));// ALL numbers are between 1 and 255
$Test1 = aryXOR($Test1,$ary1);

	//GET THE VALIDATION BLOCK and test it
$ary1 =  substr($Test1,0,6);
if ($ary1 == VALIDBB) echo 'VALIDBB is VALID '; else echo 'error VALIDBB is NOT VALID ';
$ary1 = strlen($Test1);
$Test1 =  substr($Test1,6,$ary1);
echo '+ Decrypted string = <b>'.$Test1.'</b><br />';
?>
<h3>End of Test for PHP Simple Crypt</h3>
</body></html>

Open in new window

If i knew how to translate ur php encryption code to delphi i wouldnt have posted here :)

TPLockBox works great, but still, the result differs than the encrypted string in php..

I'll try DrDamnit's solution tonight :)
DrDamnit ur soluiton didnt work. i think my host doesnt support pgp..

Can't someone just create a function to encrypt a string with delphi, and a php function to decrypt it :(
>>Can't someone just create a function to encrypt a string with delphi, and a php function to decrypt it :(

We can help you find a solution, but we are not here to code functions for you. That's what hiring a professional programmer is for.

Ask your host to install gpg. See if they'll do it.
Is there a salt involved?  Perhaps PHP is using a salt and Delphi is not (or vice versa)
aikimark:

To which solution are you referring?
@DrD

I'm catching up to this conversation.  I was responding to the comment that TPLockbox doesn't generate the same value as PHP.
@aikimark:

I have had that problem before. It most likely is a result of the salt being generated differently in Delphi versus PHP. I once wrote a key generater for some software that I wrote in VB6. I remember that I had a problem with the keys being generated inconsistently when I was referencing DLLs in Windows versus trying to accomplish the same thing with PHP on the linux side. (for when customers wanted to register on the website... I had to give them a key to activate my software).

For instance, generating an MD5 hash in Windows may or may not generate the same hash in Linux. It depends on what you're using as the source generator. This is one of the reasons I always use gnu core utils for windows rather than just some random hash generator. You can download md5sum.exe from the internet to your heart's content, but unless it is the GNU version, it won't generate the same hashes as the standard md5sum binary on a Linux box.
JealousyPrince
The asker is having the same problem.

The solution is that he has to translate his code into PHP, and the encryption has to be done from scratch. He can't use a DLL on the Windows box unless it produces the EXACT SAME outputs as the Linux version. that's hard to do unless you use a GNU dll / binary or something that has been standardized.

God forbid he's using Borland. They do everything their own way and are just flat obstinate.

Of course, if he IS using Borland... he should be able to compile his encryption code on Linux, then he can use shell_execute from PHP to generate it.... .that's a thought.

What say you, JealousyPrince? Can you compile a quick binary on Linux so we can use shell_execute from PHP?
If the two operating systems are little-endian and big-endian, the algorithms need to accommodate that difference.

In this case, TPLockbox is not (legacy) Borland code.  It comes from the former TurboPower.
Yeah. What you said. :-)
I'm using delphi on windows, and my web server and php are running on linux. I can't compile any binary on linux because im not using it. My webserver is hosted on bluehost.com.
I use bluehost too. They're pretty good.

Are you on a dedicated server or a shared one?

Unless you're on a dedicated box, we are down to translating your code to PHP.
I'm on a shared one :)
Translation it is. :-(
I can provide the delphi side encryption routines and they could also be as a soap service but the php side I dont have code for.  if interested let me know.
JealousyPrince, I have little time now to do any code work, I copy and pasted the PHP code I posted from earlier work of mine, however when I tried to figure a Delphi translation, it will take some time because I have not done any crypt in delphi before. But any crypt code is not an easy, short time endeavor. If you do not find a solution before, , maybe this weekend I can see if I can find time to try a delphi encrypt function. But I have many work and personal commitments, and EE will have to wait.
So far no complete solution :(
Some info that might be useful... Even the basic base 64 encode function in php does not generate the same value generated by any base 64 encode function in delphi..

So its not about any Salt involved or about the complexity of encryptions, its even in the basics.. This is really starting to puzzle me...
As aikimark pointed out in a previous post:

"If the two operating systems are little-endian and big-endian, the algorithms need to accommodate that difference."

Just using the basic functions is not going to produce the same output. It's like taking a spanish word and translating it in chinese. The thing is still the thing, but the word itself is VERY different.
hmmmmm.. but I understand from this page http://en.wikipedia.org/wiki/Endianness that linux and windows are both running on little endian architecture
If you read down further...

[quote]Big-endian operating systems:

AIX on POWER
AmigaOS on PowerPC and 680x0
HP-UX on Itanium and PA-RISC
Linux on MIPS, SPARC, PA-RISC, POWER, PowerPC, and 680x0
Mac OS on PowerPC and 680x0
Solaris on SPARC[/quote]

==============
The endian-ness of Linux depends on the hardware on which it runs.
SOLUTION
Avatar of Member_2_248744
Member_2_248744
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
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
Slick, I really appreciate your time and work..

I don't really want to tell u this, but still, the php code u wrote generated a different value than the delphi function u wrote lol.. By the way, on the delphi example, For the same string, whenever i click on the button, it generates a different encrypted value.. So a new encrypted value would be generated on every click :S
OK, the encryption function uses RANDOM bytes to change the output every time, as I said, these different outputs ALL wuold give the correct decryption in the PHP function in my tests

sorry that all I can do to day, tomorrow is another head wack
JealousyPrince, , I re-read your last post, and I am not able to understand when you said -
"the php code u wrote generated a different value than the delphi function u wrote"

So, I guess I'll ask these -

in my post ID:33506867 I gave delphi code for unit Cryptoe, I guess that this compiled and ran in your delphi version? Did you look at the output in a TLabel or TEdit to see the hex text generated from InCrypt() ? Did the TReCrypt returned have the "Good" as true?

in my post ID:33507002 I gave PHP code for the UnCrypt( ) function, I do not see that the php UnCrypt( ) and the delphi InCrypt( ) will ever have the same output ( generated a different value ).

Perhaps in my state, I did not explain well (my usual here at EE), The InCrypt() does the Encryption - and the UnCrypt( ) does the Decryption of hex only from the delphi InCrypt()

I did not give you an example of how to use the php UnCrypt($hex) function, so here some php I used to test this stuff -

<?php
require 'cryptoe.php';

$bo1 = (empty($_POST['bo1'])) ? '+' : $_POST['bo1'];

// get the UnCrypt input string however you like in php $_GET  $_POST or any other way,
// to get the hex string from the delphi  InCrypt()

if ($bo1 != '+'){
$deCr = UnCrypt($bo1);
if($deCr[0]) echo $deCr[1]; else echo 'Failure '.$deCr[1];
}
?>

so, in your testing of the UnCrypt($bo1);  is the $deCr[0] true, if true is the $deCr[1] the string you put into the delphi  InCrypt() ?
if $deCr[0] is false, what is the error message in $deCr[1]

sorry, I just noticed that I forgot to comment out a couple of debug echo statements in php UnCrypt( ).


Ok Slick, Its 50% working :o

In delphi, it showed me that incrypt function "was a success"

In php, this was generated:
hhelen= 19
18 Ran2 is 97
17 Ran1 is 128
Good 4

So the word Nothin is missing, in delphi, Good 4 Nothin was encrypted while in php it was decrypted to Good 4 ... without Nothin..
I encrypted "JealousyPrince" in delphi it was a success.
In php, again this showed:
hhelen= 20
19 Ran2 is 127
18 Ran1 is 148
Jealous


Some letters are missing...
@JealousyPrince

I haven't posted in a while, but think it worth asking what version of Delphi are you using?
I'm using delphi 2010
let me ask the code-posting experts if the default string type (unicode) in D2010 might be cause of the difference in the results.
I too am not sure about the string length, But It is encoding and decoding correctly the words you can see. I do not send any data length info embedded in the encrypted hex. . . The PHP just translates the hex to byte blocks (characters) and takes the length from that (always half of the hex length). .  I do add Six bytes  (characters)  to all string Input, 4 Verification and two random keys
the  debug echo of
len= 20
says that the input string is the correct length for "JealousyPrince"

if you feel like it, at the very end of the code for the PHP function UnCrypt($HexIn), please add this ONE echo line -

$HexIn = 'K';      
$len = count($Bary);
echo 'len= '.$len.'<br />';
you might also Un comment the line
//echo $HexIn.'<br />';
to see the full decrypted string (also near the end of the function code.
Okay i did what you told me..Here's the output:
hhelen= 20
19 Ran2 is 127
18 Ran1 is 148
len= 18
Jealous
Jealous
The "len= 18" length is correct at 2 less than the first len of 20, if you take 4 off for the Verification length then the output string length should have 14 characters. But the output has half of that, as if the length limit in the for loop to convert the array of numbers to characters in a string has been changed - -
for($i = 4; $i < $len; ++$i) $HexIn[$i-4] = chr($Bary[$i]);

this looks like a straight forward (simple) "for loop" to me, although there is a [$i-4] this should not effect the ($i < $len;) for the loop limiter which seem to be opting out at 10 instead of 17, , I do not have this problem on my server for some reason?

let me do another "for loop method" for byte to character conversion and see if I can figure a way out of this.
will post again in an hour or less.
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
I want to thank those for the links to the delphi encryption pages at -
http://www.cityinthesky.co.uk/cryptography.html

http://sourceforge.net/projects/tplockbox/

I had a chance to go through alot of the code that they use for encryption in different algorithms and open source like Blowfish, the Lockbox guys even had some of their own algorithms. I was able to see what is meant By the "Modes" that can be added to stuff like Rijndael 128 etc. It appears all the modes do is encrypt the key so the used key characters are more diverse in there number values. The newer algorithms were to complex for me to understand their methods, but the Cryptography - City in the Sky code had some older ones like Tea and Prc. which I could translate. For this question I figured the Tea (Tiny encryption algorithm) was enough to do the job. The original code for tea (on Wikipedia) is in C code and used 32 bit blocks, I translated it to 8 bit and changed their "block" access methods, so it deals only with two bytes to use a cross byte reference to get a rotation value that is changed by 3 values in each rotation.
I do not use any Random values in these, and each function is self contained, as it does not need any other of my functions to do the job.

php code I used to test

$bo1 = (empty($_POST['hx1'])) ? '+' : $_POST['hx1'];

if ($bo1 != '+'){
$aryK = array(13,234,27,162,90,215,193,5);
$aryVr = array(139,21,222);

$ReAry = TeaDecrypt($bo1,$aryK,$aryVr);
if ($ReAry[0] == 0) echo 'Tea De- '.$ReAry[1].'<br />'; else
      echo 'Tea De-FAILED EC '.$ReAry[0].' '.$ReAry[1].'<br />';
// PHP Code for both the encryption and decryption functions
    // both functions return and array with an error code and output string
    // both functions need an Array with 8 bytes (1 to 255) for the KEY values $aryKey
    // both functions need an Array with 3 bytes for the Verify code to make sure it's real $VerAry


function TeaEncrypt($InStr, $aryKey, $VerAry){$len = strlen($InStr);
if ($len < 1) return array(101,'ERROR Input String is empty');
if ($len > 123) return array(102,'ERROR - the Input String has more than 123 characters');
$orx = ord($InStr[0]); $VerAry[1] = ($VerAry[1]+$orx) %256;
$VerAry[0] = $VerAry[0]^$orx;//
$len2 = chr($VerAry[0]).$InStr[0].chr($VerAry[1]);
if ($len > 1) {$orx = ord($InStr[1]); $VerAry[2] = ($VerAry[2]+$orx) %256;//$VerAry[2] ^= $orx; 
$len2 .= $InStr[1].chr($VerAry[2]);} else $len2 .= chr($VerAry[2] ^(255-$orx));
if ($len > 2) $InStr = $len2.substr($InStr,2,$len); else $InStr = $len2;
$len +=3;
if ($len & 1) {$x = ord($InStr[$len-1]);
	$x = (($x ^ $aryKey[1])+ $orx)%256;
	$x = (($x ^ $aryKey[5])+ $aryKey[2]) %256;
	$x = $x ^ $aryKey[$orx & 7];
	$InStr[$len-1] = chr($x);}
for ($i = 0; $i < $len-($len & 1); $i+=2){$x = ord($InStr[$i]);
	$y = ord($InStr[$i+1]);
	$sum = 0;
	for ($g = 0; $g < 8; ++$g){
	if ($g & 1) {$gs = 1 << $g;
			$bx = $x & $gs;
			$by = $y & $gs;
			$x = ($x & (255 - $gs))+$by;
			$y = ($y & (255 - $gs))+$bx;
			} else{$bx = $x & 7;
			$y = $y ^ $aryKey[$bx];
			$bx = $y & 7;
			$x = $x ^ $aryKey[$bx];}
		$sum+=7;
		$orx = ($y & 7) ^ ($sum & 7);
		$x=($x+($aryKey[$g] ^ $y) + ($sum ^ ($y >> ($sum & 3)))+$aryKey[$orx])%256;
		$sum+=7;
		$orx = ($x&7) ^ ($sum & 7);
		$y=($y+($aryKey[7-$g] ^$x) + ($sum ^ ($x >> ($sum & 3)))+$aryKey[$orx])%256;	
		}
	$InStr[$i] = chr($x);
	$InStr[$i+1] = chr($y);
	}
$InStr = bin2hex($InStr);
$len *= 2;
--$len;
$sum = $InStr[$len];
$InStr = $sum.substr($InStr, 0, $len);
return array(0,$InStr);}



function TeaDecrypt($HexStr, $aryKey, $VerAry){$len = strlen($HexStr);
if ($len < 8) return array(101,'ERROR - the Input Hex String is less than 8 charaters');
if ($len & 1) return array(102,'ERROR - the Input Hex String has an Odd number of charaters');
if (preg_match('/[^a-fA-F0-9]/', $HexStr) > 0) return array(103,'ERROR - the Input Hex String has Non-Hex charaters');
$sum = $HexStr[0];
$HexStr = substr($HexStr, 1, $len).$sum;
$sum = '';
for($i=0; $i<$len; $i+=2) {$sum.=chr(hexdec(substr($HexStr, $i, 2)));}
$HexStr=$sum;
$len = strlen($HexStr);
for ($i = 0; $i < $len-($len & 1); $i+=2){$x = ord($HexStr[$i]);
	$y = ord($HexStr[$i+1]);
	$sum = 112;
	for ($g = 7; $g > -1; --$g){$orx = ($x&7) ^ ($sum & 7);
		$y=(($y+256)-((($aryKey[7-$g] ^ $x) +($sum ^ ($x >> ($sum & 3)))+$aryKey[$orx])%256))%256;
		$sum-=7;
		$orx = ($y & 7) ^ ($sum & 7);
		$x=(($x+256)-((($aryKey[$g] ^ $y) +($sum ^ ($y >> ($sum & 3)))+$aryKey[$orx])%256))%256;
		$sum-=7;
		if ($g & 1) {$gs = 1 << $g;
			$bx = $x & $gs;
			$by = $y & $gs;
			$x = ($x & (255 - $gs))+$by;
			$y = ($y & (255 - $gs))+$bx;
			} else{$bx = $y & 7;
			$x = $x ^ $aryKey[$bx];
			$bx = $x & 7;
			$y = $y ^ $aryKey[$bx];}
		}
	$HexStr[$i] = chr($x);
	$HexStr[$i+1] = chr($y);
	}
$gs = 0;
$sum = '';
$sum .= $HexStr[1];
$x = ord($HexStr[1]);
$y = ord($HexStr[0]) ^ $x;
if ($VerAry[0] != $y) $gs = 1;
$y = ord($HexStr[2]);
$y = (($y +256) -$x)%256;
if ($VerAry[1] != $y) $gs = 1;
if ($len > 4) {$sum .= $HexStr[3];
	$x = ord($HexStr[3]);
	if ($len & 1) {$y = ord($HexStr[$len-1]);
		$y = $y ^ $aryKey[$x & 7];
		$y = ((($y + 256)- $aryKey[2])%256) ^ $aryKey[5];
		$y = ((($y + 256)- $x)%256) ^ $aryKey[1];
		$HexStr[$len-1] = chr($y);}
	$y = ord($HexStr[4]);
	$y = (($y +256) -$x)%256;
	if ($VerAry[2] != $y) $gs = 1;
	} else{$y = ord($HexStr[3]); $y =  $y ^ (255-$x); if ($VerAry[2] != $y) $gs = 1;}
if ($len > 5) $sum .= substr($HexStr,5,$len);
if ($gs == 1) {return array(202,'ERROR Verify numbers did not match');} else
	return array(0,$sum);}

Open in new window

The delphi code is also 2 functions, also self contained and works with the PHP functions above
these also return a record with output info in them, and require the Input arrays for KEY values and Verify values
maybe this will work?

test code for delphi


procedure TForm1.SpeedButton2Click(Sender: TObject);
var
str1:String;
VAry: TAryVerify;
aryKey: TAryKey;
Return1: TTeaRe;

begin
VAry[0] := 139;
VAry[1] := 21;
VAry[2] := 222;

aryKey[0] := 13;
aryKey[1] := 234;
aryKey[2] := 27;
aryKey[3] := 162;
aryKey[4] := 90;
aryKey[5] := 215;
aryKey[6] := 193;
aryKey[7] := 5;

str1 := 'A Test';
Label1.Caption := str1;
Return1 := TeaEncrypt(str1, aryKey, VAry);
Label5.Caption := Return1.Out1;
if Return1.Error = 0 then Edit1.Text := Return1.out1 else
    Label5.Caption := 'Error Code = '+IntToStr(Return1.Error)+': '+Return1.out1;

Return1 := TeaDecrypt(Return1.Out1, aryKey, VAry);
if Return1.Error = 0 then Label2.Caption := Return1.out1 else
    Label2.Caption := 'Error Code = '+IntToStr(Return1.Error)+': '+Return1.out1;
end;
type
  TAryVerify = array[0..2] of Byte;
  TAryKey = array[0..7] of Byte;

  PTeaRe = ^TTeaRe;
  TTeaRe = record
    Error: LongInt;
    Out1: String;
    end;


function TeaEncrypt(InStr: String; aryKey: TAryKey; VerAry: TAryVerify): TTeaRe;
var
i,len,len2,g: LongInt;// ,ke
pIn,pMem,pTa: PByte;
x,y,sum,orx,gs,bx,by: Byte;

begin
Result.Error := 101;
Result.Out1 := 'ERROR - the Input String is Empty';
len := Length(InStr);
if len < 1 then Exit;
if len > 123 then
    begin
    Result.Error := 102;
    Result.Out1 := 'ERROR - the Input String has more than 123 characters';
    Exit;
    end;
GetMem(pMem, len+16);
pIn := pMem;
pTa := PByte(PChar(InStr));
orx := pTa^;
pIn^ := VerAry[0] xor orx;
Inc(pIn);
pIn^ := pTa^;
if len > 1 then
    begin
    Inc(pIn);
    pIn^ := VerAry[1]+ orx;
    Inc(pIn);
    Inc(pTa);
    orx := pTa^;
    pIn^ := pTa^;
    Inc(pIn);
    pIn^ := VerAry[2]+orx;
    end else
    begin
    Inc(pIn);
    pIn^ := VerAry[1]+ orx;
    Inc(pIn);
    pIn^ := VerAry[2] xor (255 - orx);
    end;
if len > 2 then
    begin
    Inc(pIn);
    Inc(pTa);
    CopyMemory(pIn, pTa, len-2);
    end;
Inc(len,3);
if Boolean(len and 1) then
    begin
    pIn := PByte(LongInt(pMem)+(len-1));
    pIn^ := (pIn^ xor aryKey[1])+ orx;
    pIn^ := (pIn^ xor aryKey[5])+ aryKey[2];
    pIn^ := pIn^ xor aryKey[orx and 7];
    Form1.Label4.Caption := IntToStr(orx);
    end;

pIn := pMem;
len2 := ((len-(len and 1)) div 2)-1;
for i := 0 to len2 do
    begin
    x := pIn^;
    Inc(pIn);
    y := pIn^;
    sum := 0;
    for g := 0 to 7 do
        begin
        if Boolean(g and 1) then
            begin
            gs := 1 shl g;
            bx := x and gs;
            by := y and gs;
            x := (x and (255 - gs))+by;
            y := (y and (255 - gs))+bx;
            end else
            begin
            bx := x and 7;
            y := y xor aryKey[bx];
            bx := y and 7;
            x := x xor aryKey[bx];
            end;
        Inc(sum,7);
        orx := (y and 7) xor (sum and 7);
        Inc(x,(aryKey[g] xor y) + ((sum xor (y shr (sum and 3)))+aryKey[orx]));
        Inc(sum,7);
        orx := (x and 7) xor (sum and 7);
        Inc(y,(aryKey[7-g] xor x) + ((sum xor (x shr (sum and 3)))+aryKey[orx]));
        end;
    pIn^ := y;
    Dec(pIn);
    pIn^ := x;
    Inc(pIn,2);
    end;
Result.Error := 0;
Result.Out1 := '';
pIn := pMem;
for i := 0 to Pred(len) do
    begin
    Result.Out1 := Result.Out1+IntToHex(pIn^,2);
    Inc(pIn);
    end;
len := len * 2;
InStr := Result.Out1[len];
Result.Out1 := Copy(Result.Out1, 1, Pred(len));
Result.Out1 := InStr+Result.Out1;
FreeMem(pMem);
end;

function TeaDecrypt(InStr: String; aryKey: TAryKey; VerAry: TAryVerify): TTeaRe;
var
i,len,len2,ke,g:LongInt;//
pIn,pMem,pLast: PByte;
x,y,sum,orx,gs,bx,by: Byte;

begin
Result.Error := 101;
Result.Out1 := 'ERROR - the Input Hex String is less than 8 charaters';
len2 := Length(InStr);
if len2 < 8 then Exit;
if Boolean(len2 and 1) then
    begin
    Result.Error := 102;
    Result.Out1 := 'ERROR - the Input Hex String has an Odd number of charaters';
    Exit;
    end;
Result.Out1 := InStr[1];
InStr := Copy(InStr, 2, len2-1);
InStr := InStr+Result.Out1;
len := len2 div 2;
InStr := UpperCase(InStr);
pLast := PByte(PChar(InStr));
pIn := pLast;
ke := 0;
bx := 0; by := 0;
for i := 1 to len do
    begin
    if pLast^ IN [48..57] then bx:=(pLast^ -48) shl 4 else
        if pLast^ IN [65..70] then bx := (pLast^ -55) shl 4 else
        begin
        ke := 1;
        break;
        end;
    Inc(pLast);
    if pLast^ IN [48..57] then by := pLast^ -48 else
        if pLast^ IN [65..70] then by := pLast^ -55 else
        begin
        ke := 1;
        break;
        end;
    pIn^ := bx + by;
    Inc(pLast);
    Inc(pIn);
    end;
if ke > 0 then
    begin
    Result.Error := 103;
    Result.Out1 := 'ERROR - the Input Hex String has Non-Hex charaters';
    Exit;
    end;
GetMem(pMem, len+16);
pIn := pMem;
CopyMemory(pIn, PChar(InStr), len);
len2 := ((len-(len and 1)) div 2)-1;
for i := 0 to len2 do
    begin
    x := pIn^;
    Inc(pIn);
    y := pIn^;
    sum := 112;
    for g := 7 downto 0 do
        begin
        orx := (x and 7) xor (sum and 7);
        Dec(y,(aryKey[7-g] xor x) + ((sum xor (x shr (sum and 3)))+aryKey[orx]));
        Dec(sum,7);
        orx := (y and 7) xor (sum and 7);
        Dec(x,(aryKey[g] xor y) + ((sum xor (y shr (sum and 3)))+aryKey[orx]));
        Dec(sum,7);
        if Boolean(g and 1) then
            begin
            gs := 1 shl g;
            bx := x and gs;
            by := y and gs;
            x := (x and (255 - gs))+by;
            y := (y and (255 - gs))+bx;
            end else
            begin
            bx := y and 7;
            x := x xor aryKey[bx];
            bx := x and 7;
            y := y xor aryKey[bx];
            end;
        end;
    pIn^ := y;
    Dec(pIn);
    pIn^ := x;
    Inc(pIn,2);
    end;
x := 0;
pIn := pMem;
Inc(pIn);
orx := pIn^;
Result.Out1 := Chr(orx);
Dec(pIn);
pIn^ := pIn^ xor orx;
if pIn^ <> VerAry[0] then Inc(x);
Inc(pIn,2);
pIn^ := (pIn^+256) - orx;
if pIn^ <> VerAry[1] then Inc(x);
Inc(pIn);
if len > 4 then
    begin
    orx := pIn^;
    Result.Out1 := Result.Out1+Chr(orx);
    Inc(pIn);
    if Boolean(len and 1) then
        begin
        pLast := PByte(LongInt(pMem)+(len-1));
        pLast^ := pLast^ xor aryKey[orx and 7];
        pLast^ := ((pLast^ + 256)- aryKey[2]) xor aryKey[5];
        pLast^ := ((pLast^ + 256)- orx) xor aryKey[1];
        end;
    pIn^ := (pIn^+256)-orx;
    if pIn^ <> VerAry[2] then Inc(x);
    Form1.Label4.Caption := Form1.Label4.Caption+' '+IntToStr(pIn^)+' '+IntToStr(VerAry[2]);
    end else
    begin
    pIn^ :=  pIn^ xor (255-orx);
    if pIn^ <> VerAry[2] then Inc(x);
    end;

if x <> 0 then
    begin
    Result.Error := 202;
    Result.Out1 := 'ERROR Verify numbers did not match';
    Form1.Label6.Caption := 'FAILED Verify';
    FreeMem(pMem);
    Exit;
    end else Form1.Label6.Caption := 'Verify was Correct';
Result.Error := 0;
Inc(pIn);
if len > 5 then for i := 0 to len-6 do
    begin
    Result.Out1 := Result.Out1+Chr(pIn^);
    Inc(pIn);
    end;
FreeMem(pMem);
end;

Open in new window

@Slick812

Thank you for posting that.  

Here is a page with TEA/XTEA links
http://www.shokhirev.com/nikolai/programs/code/Cryptography/TeaSet.html
Hello Slick812;
I'm glad to hear you,  I'm one of your delphi fanatics.  I've seen some your good codes.
Sorry for this pluggin, I though Slick was gone a long time ago.
@systan, thanks for the comp, I am still gone, forever out to lunch, LOL

Yes, I had to switch from Delphi to MS Visual studio and C#, so I had no time to be in Pascal any longer, I haven't done any pascal coding in 5 or 6 years. I was doing this encryption stuff here as a blast from the past and it was some what of a challenge. I had to change over to PHP and web page development, because where I am, there did NOT seem to be any development opportunities except for web related stuff, because of the downturn of the economy.
I was thinking of maybe trying to write an article here at EE about open source (rijndael,3DES, twofish) encryption, since info about how the different components like - modes, IV, key, algorithm, and things to consider for using it are not explained much. Like the "mode" thing, untill I looked at the base code, I knew little (or less) about it, I had not seen an explanation of mode factors in all the junk I had read about encryption (at least in the PHP manual and other encryption "how to" sites). All of the open source are block sector based (usually 16,32,64 bit) for operating system optimization, I saw in the notes of the source code that they tested an encryption function by encrypting an entire hard drive. Seems like over kill for password encryption to use 64 bit blocks for a 14 character password. Maybe next month I can find time to try it, oh it's september already, this month?
lol, good luck in your php web dev and .net c# aspx? Ok; its september weekend.
>>encryption function by encrypting an entire hard drive, lol, thats a joke.  bye
Slick812, I really appreciate your help. This helped me a lot.. it is finally working :) I appreciate your time. Thank you very much
Slick812:

Outstanding job. You have gone far above and beyond, and gotten the attention of many of the Zone Advisors and Mods for such a fine contribution.

Kudos to you!
Hi,
   
       I have same problem as JealousyPrince., I try to compile & test code provide by Slick812 it doesnt work on Delphi 2010.  

       I have source attached both Php & Delphi project.  Expert please help...

PhpAndD2010Encrypt.zip