PHPBuilder - Securing Data Sent Via GET Requests Page 2 Page 2

RSS Twitter

Securing Data Sent Via GET Requests Page 2 - Page 2

by: Hillel Aftel
December 13, 2007

We need the key names to also be ASCII codes, so we use array_combine, and tell it to get both the key names and values from the same array. What we now have in $ascii is an array that consists of identical key/value pairs. $ascii[32] == 32, $ascii[79] == 79, and so on.
$handle = fopen($saltfile, 'x');
This opens our file for writing. The 'x' argument will cause the file to be created if it doesn't already exist, and throw a PHP warning if the file does exist.


For added security, you can opt to allow periodic regeneration of the salt file by changing the 'x' argument to a 'w'. This will allow overwriting of any pre-existing salt file.

I specify the 'x' argument here by default because accidental overwrites of the salt file while the encode/decode functions are in live use can be hazardous. Any data that's in-transit at the time of the overwrite will end up garbled after being decoded. If you decide to specify the 'w' argument, I recommend moving mine.php to a separate directory. That will allow you to run this script as much as you want without having to worry about accidentally overwriting the in-use salt file.

/* The file we're creating will need to be a PHP include file, so we need to wrap its contents in PHP start/end tags. In this write operation we also start declaring the array, which I've chosen to call $salt. */
fwrite($handle, "<?\n".'$salt=array('."\n");

// Since we want to output 10 different sets of data, we begin a for() loop that has 10 steps.
for ($i=0;$i<10; $i++){

	//Here we save the present state of the $ascii array, because we'll be using shuffle() on it, which will permanenetly change it.
	$rawAscii = $ascii;

	// Shuffle the array values.
	/* 	shuffle() erases the key names from the array, so we need to assign them again by using array_combine(). 
		We get the key names from our original saved $ascii array. */
	$newAscii = array_combine($ascii, $rawAscii);
	// In our next write operation, we define the first dimension of the $salt array (with key names 0 through 9, determined by $i).
	fwrite($handle, $i."=>array(\n");
	/* 	Now we loop through the $newAscii array, writing code to the page that will define the bulk of the array. 
		We need to start the loop at 32 and also add 32 to the max loop iterations, because our array's key names 
		start at 32. The rest is fairly self-explanatory. */
	for ($x=32;$x<count($newAscii)+32; $x++){
		fwrite($handle, $x.'=>'.$newAscii[$x]);
		if ($x<count($newAscii)+31){fwrite($handle, ",");}
	fwrite($handle, ")");
	if ($i<9){fwrite($handle, ",");}
	fwrite($handle, "\n");
fwrite($handle, ");\n?>");
echo 'Done.'; 
Upon running the code above, a PHP file will be output, containing a single large two-dimensional array definition.
Now we can start writing the encoder/decoder functions. I call the encoder ob(), short for "obfuscate," and the decoder deob(), short for, you guessed it, "deobfuscate".
First, we'll need a source of pseudorandom data. We'll use this data to make a choice from one of the 10 data sets in $salt, as well as to provide some of the random "dummy" digits we'll use to pad the encoded string. I use microtime() for this, but there are many different ways to get pseudorandom data in PHP. microtime() gets the UNIX timestamp down to the microsecond, so most of its digits are sufficiently random for our purposes.
function ob($in){

	// Before we do anything, include the salt file.
	// Get the current microtime.
	$m = microtime();

	// Take various digits from microtime to use as dummy characters.
	$t = substr($m,3,1);
	$v = substr($m,5,3);
	// Take a digit to serve as our choice from the $salt array.
	$which = substr($m,2,1);

	// Loop though the characters that make up the input string.
	for ($i=0; $i < strlen($in); $i++){
		// Get the ASCII code of the character using ord().
		$ascii = ord(substr($in,$i,1));
		// Get the corresponding replacement ASCII code from our chosen key of the $salt array and append it to a variable, 
			thereby contructing the encoded version of the input string.
		$newIn .= chr($salt[$which][$ascii]);
	/* Finally, stitch together and return the complete encoded string. $v and $t are random dummy digits. $which is the 
		digit that tells the decoder which data set was used to encode this string. We send this along with the actual 
		encoded data; thus the advantage of not having to send along a separate decode key, as in other encryption methods. 
		We also need to make sure our output string is transmittable via URL, which we do using urlencode(). */

	return urlencode($v.$newIn.$which.$t);
Here's the decoder function, which simply reverses all the changes made by the encoder:
function deob($in){
	// Since the encoder used urlencode() on the encoded string, we need to first urldecode() it.
	$in = urldecode($in);
	// Read the character that tells us which data set was used from $salt to encode the string.
	$which = substr($in,-2,1);
	// From this point on we only want to work with the section of the string that contains the actual data that was encoded.
	$in = substr($in,3,-2);
	// Loop through each character in the encoded data.
	for ($i=0; $i < strlen($in); $i++){
		// Get the ASCII code for the character.
		$ascii = ord(substr($in,$i,1));
		// Search the $salt array values for the ASCII code, convert that value's key name (the ASCII code for the original 
			un-encoded character) to a character, and append it to a variable, thereby reconstructing the original string.
		$newIn .= chr(array_search($ascii,$salt[$which]));
	return $newIn;
First, generate the reference array file by simply navigating to mine.php from a web browser. The new file should then appear in the same directory where mine.php resides. Note that this step only needs to be done once.
Then, to call the encoding and decoding functions from your own script, first include the main script file:
Use ob() to encode data before sending it. ob() takes a single string argument, which can be a variable or a string literal:
$queryValue = ob($value);

// or,

$queryValue = ob('some query data');
Spaces are acceptable in the argument, and will be preserved in the decoded output. On the receiving page, decode the query string with deob(). deob() also takes a single string argument:
$value = deob($queryValue);
You're Done
You now have the tools you need to take full advantage of the convenience of GET requests, without ever needing to display insecure data in the client browser.
I hope you find this as useful as I have!

« Previous Page

Comment and Contribute

Your comment has been submitted and is pending approval.

Hillel Aftel



(Maximum characters: 1200). You have characters left.