Jul 19 2012

Transferring Data Securely on HTTP using PHP

Category: PHP,Tips & Tricksksg91 @ 4:23 pm

Image courtesy of MIT OCW.

Well, I have been working on a WordPress plugin and I required to transfer some data from client’s host to my host. Data is Access Token and Secrets for their Twitter account (Of course, not to store it on my host but to perform their operations on Twitter). Being sensitive data, it was required to transfer them securely over the network, keeping it secure from at MITM attacks. As a option, I can use buy a IP and SSL certificate and transfer it using HTTPS. But, being a free plugin, I really didn’t want to spend money in such things. And only option I was left with was to use HTTP and transferring data encrypted.

For this, client will register to me and avail its access token and secret (not of twitter, but for my site). There were multiple data and instead of encrypting them independently, I decided to make a class named Request which holds all the data to be transferred.  Now this request class is serialized and then that string can be encrypted.

I use following code snippet to encrypt :

[php]
$req=serialize($this->request);
$req=$this->key.$req;
$this->enc_req = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($this->acc_sec), $req, MCRYPT_MODE_CBC, md5(md5($this->acc_sec))));
[/php]

Here,

[php]$this->key[/php]

is Access key given to user and

[php]$this->acc_sec[/php]

is Access Secret given to the user.
Let’s check example of this encryption:

Object Request:

object(Request)[1]
  private 'tmp_key' => string  '___' (length=16)
  private 'tw_acc_tok' => string'blah' (length=4)
  private 'tw_acc_sec' => string 'blah 1' (length=6)
  public 'tweet' => string 'Tweet' (length=5)

Serialized Object

string

 'O:7:"Request":4:{s:16:"?Request?tmp_key";s:16:"___";s:19:"?Request?tw_acc_tok";s:4:"blah";s:19:"?Request?tw_acc_sec";s:6:"blah 1";s:5:"tweet";s:5:"Tweet";}' (length=168)

Encrypted Object

string

 'NxFivVICmrRzh/fSlvT3jeWrT8pdvWRKPPc9lpEe1g1MoYgvom2/Sg6kqm0sqQ/PeYIeJXCahQSubW78CbHzBfMcIXsBCmAistVq/XvkZUSe5Hb5OWIr1D3AiGb5943BO9E2reUKr0GJYyIS+Lxrh1mTvSdpbcu9twt7qqhay6dU77icqu8jdvDBs7XrBTTxDFNS57Cl8KYSICInrJ30nwT8CqLHZdsA4poAhZm7TeIV7xp+bUmRAF5WXV6QUlKm' (length=256)

 Now, this encrypted data is sent to me using cURL and Access Key and encrypted text is send along with it.

On my end, I have access token and secret stored in my database, so I will decrypt the request using the access secret that I have stored in my database with the requesting access token. Following code will help me to recover original Request object:

[php]
 
<pre>
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
$so=substr($decrypted,strlen($this->key)+1);
$this->request=unserialize($so);

[/php]

I have used Access Key as a salt. Of course, it’s not the only thing I am going to use to achieve higher security. But I believe, this will be enough to give you an idea of how we can achieve a certain level of security. I am not quite sure how secure this method is, but surely enough for my application.

Please feel free to post your views and comments on this. Hoping, this helped. 🙂

Tags: , , , ,