Two way encryption without mcrypt

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Two way encryption without mcrypt

Post 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
Last edited by Ollie Saunders on Sat May 13, 2006 9:05 am, edited 1 time in total.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Re: Two way encryption with mcrypt

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

i tried that, doesn't work.
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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>';
?>
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Could you show an example of the output?
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post 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)
Post Reply