Page 1 of 1

Two way encryption without mcrypt

Posted: Fri May 12, 2006 4:39 am
by Ollie Saunders
I have a url like this:

Code: Select all

http://somedomain.com/show_v.php?v=49
The page this accesses is not passworded or secure in any way but my client wants me to somehow obfuscate the v=xx bit so that people can't just change the number. I can't use md5 or sha because I need to be able to decode the number after. So I thought mcrypt_encrypt and mcrypt_decrypt would be perfect but my server doesn't have mcrypt and I don't particularly want to recompile PHP.

As far as I can see there is no encrypt, decrypt functions in standard PHP so does anyone know where I can find the code for a couple of these. I'm using PHP 4?

Thanks

Re: Two way encryption with mcrypt

Posted: Fri May 12, 2006 10:39 am
by timvw
ole wrote: The page this accesses is not passworded or secure in any way but my client wants me to somehow obfuscate the v=xx bit so that people can't just change the number.
Users can always use make up an URL and try to visit it (Admitted, the chance that he's lucky when he tries a id=2 after he has seen id=1 is greater than the one of finding id=xxx after he has seen id=xxy. But for the situations where this is unwanted there are better solutions than simple obfuscation)

Anyway, to answer your question: basic php userland encryption.

Posted: Sat May 13, 2006 9:05 am
by Ollie Saunders
i tried that, doesn't work.

Posted: Sat May 13, 2006 11:47 am
by AGISB
I have done something like this. It is not foolproof but it works

Code: Select all

$thenumber = 99
$thenumber1 = dechex($thenumber); // you need to fill up the number with 0's so every number has the same length 
$hashtest = dechex(($thenumber * 200000) + ($thenumber * ($thenumber + 666)));
The formula is kind of random and doens't matter. Most everythign works

Now we combine the hexed number

Code: Select all

http://www.yoursite.com/index.php?id=$t ... r$hashtest
The number is in hex now and if someone figures that out he cannot call the next page as he won't be able to create the controll number.

At display you only need to check the number with the formula against the control number and all is set.



Another way is to create a md5 hash with the number and a secret seed. Cut this hash in half take the appropriate number of hex nubers out of the hash fill in the hexed number and merge the hash together.

Only you know which digits are the original number and even if the intruder finds it out he doesn't know the seed to create the hash you compare the number too.

Posted: Sat May 13, 2006 1:26 pm
by Ollie Saunders
Thanks AGISB I think that this:
Another way is to create a md5 hash with the number and a secret seed. Cut this hash in half take the appropriate number of hex nubers out of the hash fill in the hexed number and merge the hash together.

Only you know which digits are the original number and even if the intruder finds it out he doesn't know the seed to create the hash you compare the number too.
will satisify my requirements quite nicely.

Posted: Mon May 15, 2006 4:10 am
by Ollie Saunders
OK If anyone is interested this is how i've done it:

Code: Select all

<?php

define('SALT','whatever string#[]899');
define('TERMINATOR','0');
define('INITIAL_POS',20);										// must be no higher than maximum length of integer minus 32


/**
 * Conceals an integer within a salted md5 of itself.
 *
 * @param int $num
 * @return string
 */
function md5IntConceal($num) {
	$num = (string) dechex($num) . TERMINATOR;  						// 0 terminator; inconspicuous
	$md5 = md5(SALT . $num . SALT);

	$str = substr($md5, 0, INITIAL_POS); 						// always starts in the same place
	$str.= $num;
	$str.= substr($md5, strlen($num) + INITIAL_POS);
	return $str;
}

/**
 * Returns the integer previous concealed with md5IntConceal.
 *
 * @param string $hash
 * @return int
 */
function md5IntReveal($hash) {
	$shortHash = substr($hash, INITIAL_POS);					// first part not required
	// better than preg_match_all
	for($i=0,$j=strlen($shortHash);$i<$j;$i++) if($shortHash[$i] == TERMINATOR) $match[] = $i;
	$matchLen = count($match);
	$i = 0;

	// trial and error, go through all the occurances of terminator see if the md5s match
	do {
		if($i >= $matchLen) return false;						// nothing concealed in here
		$hexNum = substr($shortHash,0,$match[$i]);
		$i++;
	} while($hash == md5(SALT . $hexNum . TERMINATOR . SALT));
	return hexdec($hexNum);
}

// test

$numbers = array(1,5,104,65350,234,0);
echo '<pre>';
foreach($numbers as $num) {
	$encode = md5IntConceal($num);
	echo $encode . '<br />';
	$decode = md5IntReveal($encode);
	echo $decode . '<br />';
	var_dump($decode == $num);
	echo '<br /><br />';
}
echo '</pre>';
?>

Posted: Mon May 15, 2006 5:03 am
by s.dot
Could you show an example of the output?

Posted: Mon May 15, 2006 5:17 am
by Ollie Saunders
Well yeah but its working fine.

Code: Select all

17acfd544a4b53648df5108101b79565
1
bool(true)


977426cdd201efbab31650b891848d73
5
bool(true)


1833347a9473c1175382680398931b9f
104
bool(true)


291fd992784a7d91db03ff460e8ce827
65350
bool(true)


7e0f20dae81d0dcaff37ea0bcf1e2c33
234
bool(true)


a64840dfdf3a2d5cdf62004d26a1aebb
0
bool(true)