URL Obfuscation

In a recent project there was a need to pass parameters on a URL in the form `script.php?coupon_id=1&advertiser_id=3` and prevent the user from being able to tamper with the parameters.

One way of doing this was to pass the values as a serialized array, which would look something like `script.php?aMyArray=a:4:{s:9:"coupon_id";i:1;s:13:"advertiser_id";i:3;s:7;}` the result of that is not very elegant and any php developer would be able to tell that what was on the URL was in fact a serialized array, and would still be able to tamper with it.

So the final solution made use of php's built in crypto functions. Here is the code broken down.

Function for Encrypting the array for use on a URl

<?php

/** Config Parameters **/

// Do change these vaules  
// We Generated them using Linux command line
// # openssl rand -base64 24
// This will generate 32 character Strings

$DefaultConf->UrlKey 'dael1m4gSQIM3AyKisaa3QWjs5TtXrfLDKXZ66MMZuZ3';
$DefaultConf->UrlIv  'FiBVoCyjCyZv6Q6cl8i6mSshlKUBe2HcnstXO4eNWqQK';

function 
fUrlEncrypt($aDataArray)
{
        global 
$DefaultConf;

/** Feel Free to use different Encryption to suite your need
    check the PHP Manual for other Options 
*/
        
$aDataArray mcrypt_encrypt(MCRYPT_RIJNDAEL_256$DefaultConf->UrlKeyserialize($aDataArray), MCRYPT_MODE_CBC$DefaultConf->UrlIv);
        return 
base64_encode($aDataArray);
}

   

Usage:

<?php

$aMyArray = array();
$aMyArray['coupon_id'] = 1;
$aMyArray['advertiser_id'] = 3;
$aMyArray['user_id'] = 200;
$aMyArray['padding'] = 'Someothertexttomakethismoredifficult';


print(
"\n ORIGINAL: \n");
print_r($aMyArray);


print(
"\n ENCRYPTED: ");
$sEncryptedUrl fUrlEncrypt($aMyArray);
print 
$sEncryptedUrl;

Output:

ORIGINAL: 
Array
(
    [coupon_id] => 1
    [advertiser_id] => 3
    [user_id] => 200
    [padding] => Someothertexttomakethismoredifficult
)

ENCRYPTED: cW5y44u6ScszOSctm+QhgFKtEbO3MrL6W1J01zu0jRR2Aw1hhp3F7phLV5O7gYiu+nyhlYlc3qNNSJGn5CTp5rhujH+YIdaqPkqgklbdeWDEZUA7K74ZgfMCNCHuNhCoYTsa34C9kHxwTZLQtrLC5FLNrBCM0Pq69uIPLPWi/zqXmEKlIaaBu7JnG31f81WMUdzd8zIEwvb3L9T0eRLehw==

Now one can use `script.php?coupon=cW5y44u6ScszOSctx....` don't forget to url_encode this string before using it in your URL


Function for Decrypting / recovering the data from the URL:

<?php

function 
fUrlDecrypt($sData)
{  
        global 
$DefaultConf;
   
        
$aDataArray base64_decode(urldecode($sData));
        
$aDataArray mcrypt_decrypt(MCRYPT_RIJNDAEL_256$DefaultConf->UrlKey$aDataArrayMCRYPT_MODE_CBC$DefaultConf->UrlIv);
        return 
unserialize($aDataArray);
}     
      


Assuming the script.php?coupon=cW5y44u6ScszOSctx... is our script that will be processing the requested coupon.

Usage:

<?php

print("\n DECRYPTED: \n");
print_r(fUrlDecrypt($_GET['coupon']));

Note: If you are passing something other that a $_GET variable don't forget to urlencode the string first.

Output:

DECRYPTED: 
Array
(
    [coupon_id] => 1
    [advertiser_id] => 3
    [user_id] => 200
    [padding] => Someothertexttomakethismoredifficult
)

Now that you have the Original Array you can have your script retrieve the correct rows from your database or do what ever processing you need to do with the values contained in your Array.

Some may find that using 256Bit Encryption is overkill, so feel free to use a simpler Encryption, but I think that this illustrates how to pass potentially huge amounts of data on the URL securely in a relatively small URL

Posted on: Tuesday, September 10th 2013

Generating Unique Transaction ID's

On some E-Commerce Sites, once a customer finalizes his purchase it's nice to give that customer a reference ID or Number that he can use to enquire about his purchase. This number is included in the Confirmation Message and Email. Here is Simple Code to achieve a Unique Transaction ID.

<?php
$MyTranID 
=  strtoupper(md5(base_convert(uniqid(),16,36)));

print 
"\nMyTran Size: " strlen($MyTranID);
print 
"\nMyTran: " $MyTranID "\n";


Output:

MyTran Size: 32
MyTran: C265AD9E3759F8BE90F49C6F75355DBF

Some May feel that 32 Character is a bit long for a Confirmation Number, in that case you could use the first 8 Chars using substr, This may not be unique in the long run, but short Transaction ID in combination with the transaction Date would allow one to find / identify the Transaction in question


Posted on: Wednesday, September 11th 2013

Storing Passwords to a Database

Passwords are a fact of life, so if your application has a password protected section you need to store the passwords in the database. We should all know by now that storing them in clear text is not a good idea. In the past I've used MD5, but now days that can be brut forced quite easily.

Another Way is to double HASH the value with a salt , if you can keep the salt safe, it makes the passwords cracking more difficult but not impossible. Much better than clear text or Single MD5. If you suspect someone got access to your database user data, the first thing you should do is reset all passwords and notify your users to reset their passwords.

<?php

/** This script is designed to run from the command line **/
/** # php filename.php  **/

// Do change the Salt vaules  
// We Generated them using Linux command line
// # openssl rand -base64 33 
// feel free to increase the lentght of the saled by
// changing 33 to some other value lets say 256

$DefaultConf->password_salt 'H1G4z76AL27gogwGxwQp5MPwofq98jedjbL0sbN';

$sPassword 'myp4ssw0rd';

$sPasswordHash sha1(($DefaultConf->password_salt.$sPassword).$DefaultConf->password_salt);

print 
"\nPassword Hash to Store to your DB: " $sPasswordHash "\n";

Output:

Password Hash to Store to your DB: d3e4a1a54a6b454c3a5aea8d92ba98b12f3c777d

You can store that value to your database, and the next time the user attempts to login you hash the password in the same manner and you compare with the value stored to the database and take the appropriate course of action.

Posted on: Thursday, September 12th 2013