How to store keys (RSA) ?

The last post was about handling RSA cryptosystem in PHP. This post is covering a small aspect of the last post.

Once keys (Public and Private) are generated there should be a method of storing the keys, both private and the public keys to use later. Since the keys are having a specific format you are not able to store them in a raw format. It doesn’t work the next time when you try to use them.

There are few formats and methods we can use. In the last post, the generated keys are in PEM (Privacy Enhanced Mail) format. Dont get confused with that. I am suggesting a technique to store the keys. There are many other ways to get this accomplished. Among them base64 encoding/ decoding would be quite handy and easy.

PEM formatted private key is noted below.

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,CEC7DF536C0F4B98

sOBuGCgafYqmuOwzmG+HKD9Rq1fkL5PCt1ZfDF2lwKLoSjS3Ao68Sb3vrelkF7Df
3RwUOXL+G9HOMgmEmS6e+DacesaPHipvdjTca7k5z6A2ndRaDPB+6GuuswVBzbwm
CbRerep9G1BEyRY0z/3LKCgr1IbcpiPGAtmfEr/aTuqZURkY3eEosGP9Mn66b7Tr
bYaQOYE0tX2hI6GkQHJP9JGBsVLOA9iQ/QYtF3CjxFUTB3fWR3qPV/36SucBxlPx
pNWHPoXQixIAl9wvmJ0lA+y6mkWe0GBPBRWAF1Xum28Ujaw3E+95Vcxp7e2HvehX
xwpG10Xq5OdO0F+Ov4YULGe/VvJuQh6Lwb96qjserkzdfPNRxXm5vudPCRSQylxz
6N4xYUxtZoOOZ0A3znpTS13F+pTHAjAfHEutd17qTAApSlnOUz/CX7NI070pw+Eq
4QjQ9IJju14XBFqjbK8bdsaIAhZvZgTZY995t5F9R30Rf99XpIWTcPIVpX9Zb8nx
Lfxw0ok0Io2mdymy4jttopXgbrt+mky3zf7d2oxengefreuHH0SUYwrCVk5xKZju
NVZPPXP0Sx/f6nyHdv+MFh9mB1YrbuMeP4LSK3tsgVb2P4k3FOaQGwMU32k5KaBP
R97i7RowhiALljGvMouxo87QxdYUZJTVvcDj/42PiGZP6fQO1X35TWkr8INvGAqB
sUKMLZPsZahaSxWZ5uoIiOfjB8RdvmNB6D5DHUviIavkAFLUtZOT18apXhLzrKMO
f9p7WZP5yGVdD0AnWX9NP157VHQYZGNOu6ZHzPMJ38R4+uEtv7mf55A9FQPrYAXK
NOqxpXd5XNmM2Yl+MVlZJ7IXf1TCZicbG+DjQYyQHg9nK43eG61waZCM4EmjF0Vs
hx/FtelrmV5pw1vna0N8rmF4WG6+e6ruZ0ovFOFCsqb5630UJkkRqWKxkN/2t3FW
2LMjNchpswSoe4WQwIAoM+piv31VR+rGYcreDsJprXVPyzTVUZgxUdb7ku2HN1KH
9z336Aot9snJkkdZrsoqoOMCpQuUP987aMS5bQyHmJDWTo7XxPW2BxLYUjTeeqRA
GAk0LVOzTVP57TYi4Ay6cmrdnBsmv6qlCIxOspx83MzYqjOLqQuEpvag1YYTIgzX
6kc5LGpiP4Itd8EEqSdBkRUTetuDsoHdRfHna16i8YS3HwHTei2eF3BbpLXPAt26
aPsSnACs+fTz1GP/Rr7s2kMmnChh/z6afTJVGG1E6fXBOHozY+S2MO3wNr6hupPp
dtP23x88Gjh3TaPdQ7qkg2j0SqDdLLCekvmGhGyT3gKLCAF60NxrJETlHKfyrPHO
BM26pGB22KsYwUlihXTxFlSfP81tY9NQxpu/GjBCutWvQl74BvghHFQUJKIQuqa+
IgtkY+l4zTZ+meSjYvSzA/r3KfLdTIQt5eIVhDs1Jhont2zPBZ1x7n7T+eevj7FP
zVrV5H8ukp38KhtlJ05ufy6628qBOlelsfMExxGxNZICIh40sGaQO3DsBrNlgAln
D+XcWPK81uBIN9jYeRbtTu00n7/bQrJyIHAbKeU+wAb0TF87ets2VPzIwTpdxzc2
-----END RSA PRIVATE KEY-----

Base64 encoded key (note that it appears as a single line, no line breaks).

LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KUHJvYy1UeXBlOiA0LEVOQ1JZUFRFRA0KREVLLUluZm86IERFUy1FREUzLUNCQywwRTc5NTEyREZBRjJBRTE2DQoNClN3Qllra3J4OTAxTzVMa0M2aUowUWVTNGNLUFRtVm92L1hjRzE2Z1dSZE9HbEdqNkg1blAyRnkzRkFoQSs2SGUNCmllZzV0SXBoWHljV1ZST3Nta2FMbXJxb1hoZ3NjZDJ6cE9DM1RHQ1JqZ0xnUkovcXJyczRhM2dwM3JOVityN3ANCmg1L0MwS0ZmR3hPWHRrOWFXZGRVOW5MY0F5WUdWQXI0Ui9Sdkc4YkowMDZpZ3RwNzgrVG00SW9IendYZy9udmcNCkZqNjJ6NGRFQ1B1U0lvZWswL3pxYVVlcVJuelppTlgxaWtwMmNBTisyN1JadnpBY1lBUk5pdmpEMWdTM0tXL1gNCmJoblhoYjFWQnFjbks5NE90My9SZ090cGRjOVJFVW5INk9na3RJOTBKK0ZKelM4Y21KMzhvUi9EdEtrM040QVANCnBNM2lXWTd0Qmg3OE42TVpFa2Fna0hxUzYxTGEvVFBmSE5Sb1ZyVW9sNExVZCtrMHhjT1RBWmxLbjJyOXZVWHkNCjhWaGRwc1NlNVRqSFlaWXJkU3BBTlA1MXV0RHFxTFhwSkx3ZkE4ZXVKQ0dOUU9IZDFjdER2WFEvc0xDUm1UT0cNCjJqN0Z6YXMwRThrdlh4a0hQYUkvdFA4Ull2Y3lkUFJyQUZ0RFBXTkxQQnE1VHBhYit5V0RZbUE3bGs5c0Z2c0ENCjNEY2VaRzI3QllBYmNoRCtDTUFTSEpNMk5jem54WkRvajBOQlMvZFp6Q1R0QU9vcVZZSnNSU01kR0JuQXBSVS8NCmpPRVUrYVNGKzRtMyt1RTJOUlJTOXhRcVBTMUt1azVzdFZLcWdVYzdwVmtGWndZYTZPWFNDTTBQOVE5UVFCa3ENCkNvRG1CSG5SU1MybFdTNXkyVkN0b0VWaFlCMDV6aFV4Y3pXWWR0eG9DVmx2RzcrM0FDL0luU1NHVGVYeXhzeTYNCkkzRUg5NHhZM25yamtPZ1ZRU1RkWjc1akJxS3FHdmNQVTlLSjBRVzJqTjAyUHJxNWFXRkNkbkliYTVjRS9yaTQNCjVEOURvcys4ZnNDNGdiYXJyK21ZOTl3KzdSaWZadEUybGlzaWVCZEFxR1NiRDg0MWJ0TERXOUl4cU5yOXl0eWYNCjgrOS9kWUhhTG9ySHRXYXgySkJ0SVhOdHpSVjUwQVhrTDk2ekhXMFVhSExRaFZqcEt5alhaWTNrSWV2amxkZjUNCkVuc2JLemxCeENOdmJON3NIdDhBWFVYL3E5Sk9ENHowNkdnMmJPOW5mWngraUx6QklnQVBDcGpFQTdQZlBMWHgNCiswRmJuR3QvWHozUjd0dHM2ejhvSWZMLzN4aURnSWdBZkxjSi84L3Vqa2JGMEVtMzlJZ25tWU5JemVrNDlZVTINCllOTFo2clJiL1RtZDVRRWQxNzcxRHhaZWFKdFdxdzAySUNBQnpjelV1NjNhSFdyRkZDZVlPOWRxRWFUa3EzTmwNClR2bFNyYlNyV0E2by9GUlR0Tks5NEZzZG9QbFlXU09zb3Y5bHE0bzNDNjJIZ3NubnQ2VkNob2FXa2VlRDRUajYNCkErV2FIVHVkbklseWM1NXlKSm4xRkd6dWRUaitDc3owL3JMSTMyLy96V1BUZHdVY3FnZVVjL0FCWnNVMFBhOXQNCjNiQTlnTmQ2ZE55aW5pcVVKYStYS2d2b0pHb0M3eTNPc3hMcHIvRnRnMDZRZ0lJQjlmckhHRzJZcHY4VHFoTFcNCnJkaWpCWnBLaE1HUFBTSVI5VmFzUVd0UnphZTdCYzVqd0Q3b09BVmU0b010ME5XdVo5d2gzQ2pFOWRNTVVFYkQNClNDRzIwYkVBd2xSV2RrMzQvZ2hWVmFVSHdlc1J1cTNmRUlqbTA3aytOYVdhMGU2SmxsSnliOThMZVE5SWYvUloNCndjRVo4T3NpN0lsQnJHOHRsanJPbnNuYTM3M0dsZFIyNDN4UUp2VGw2V1lxWCtPampMQjd0dUtvUzJkWTJsVk8NCmxwUEUzdEVwL2U5NGtaMEx3Yk9FQWxTSkVHdjk5eG84MzJ5TG90ZmZGTG40cURFbnY4dUh2aDBDQ2VsY1hKVjENCjBXdmFoOWMwaCtUZGVydWgvZFJoa0NpZjBuMUUyN25hbFBMeS9oQVJJSHpZQUtGbmRUZjZyNGVESmpqalUrcTQNCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0t

You can simply use a “TEXT data typed” filed in MySQL table to store base64 encoded key pair and then when it is needed just base64 decode and use it. Even you can apply further encryption against the base64_encoded string to make the key much more secure. You can hash the base64_encoded string and create signatures of the keys as another security measurement.

Simply use the base64_encode( ) and base64_decode( ) functions in PHP.

$encoded_key = base64_encode(myRSA::$privateKey);

$private_key = base64_decode($encoded_key);

NOTE: base64 encoding doesn’t provide any additional security, it is purely assisting towards storing/ passing the keys in a more comfortable way. Therefore you need to use an additional security layer (eg: database data encryption) on top of the stored keys to make it much more secure.

RSA cryptography in PHP (How To?)

Being security is one of the utmost considerations in current web site/ application development process, I am sure you have spent a lot of time writing codes to handle encryption in your applications.

In this article I am trying to present one of my favorite ways to solve this issue, the RSA encryption/ decryption handling in your PHP development.

This is quite straight forward as I am using PHPSecLib package. I was using openSSL library for PHP for few years and recently started dealing with this package. It is pretty cool implementation so I started loving it.

First of all you need to get the package, it is available to download[1] and it comes with MIT license[2], GPL compatible[3].

If your intention is to use PHPSecLib only for RSA encryption and decryption I suggest including only two directories which are Crypt and Math in your production environment.

First step towards the RSA encryption is to create the public and private keys. Note that I have secured the keys with a passphrase.

$rsa = new Crypt_RSA();
$rsa->setPassword('pa$$wrd5');
$keys=$rsa->createKey(1024);

echo $keys['privatekey'];
echo $keys['publickey'];

The code is self explaining. createKey() method is taking the bit value of the key and output an array which contains the Private and Public keys. setPassword() is optional, you can omit it if you dont want to create the keys with a passphrase. If you want to use 2048 bit key then provide 2048 as an argument in createKey() instead 1024.

Once keys are ready you can start the encryption. I am using using the public key. Passphrase is not required when encrypting.

$rsa->loadKey($keys['publickey']);
$plaintext = 'Text to be transmitted securely !!!';
$ciphertext = $rsa->encrypt($plaintext);
echo $ciphertext;

Decryption goes as follow (using the private key), note that the passphrase is mandatory:

$rsa->loadKey($keys['privatekey']);
$rsa->setPassword('pa$$wrd5');
$re_plaintText =  $rsa->decrypt($ciphertext);
echo $re_plaintText;

I have written a static class to demonstrate how encryption can be carried out. Please check the following:

***DO NOT use this code in your production env as the code lacks lot of fine tuning and security measures***

This is just to illustrate how the PHPSecLib can be used in a code


<?PHP

include('Crypt/RSA.php');

class myRSA
{
	public static $privateKey = '';
	public static $publicKey = '';
	public static $keyPhrase = '';
	
	public static function createKeyPair()
	{
		$rsa = new Crypt_RSA();
		$password = base64_encode(sha1(time().rand(100000,999999)));
		$rsa->setPassword($password );
		$keys=$rsa->createKey(2048);		
		myRSA::$privateKey=$keys['privatekey'];
		myRSA::$publicKey=$keys['publickey'];
		myRSA::$keyPhrase=$password;
	}

	public static function encryptText($text)
	{
		$rsa = new Crypt_RSA();
		$rsa->loadKey(myRSA::$publicKey);
		$encryptedText = $rsa->encrypt($text);
		return $encryptedText;
	}

	public static function decryptText($encryText)
	{
		$rsa = new Crypt_RSA();
		$rsa->setPassword(myRSA::$keyPhrase);
		$rsa->loadKey(myRSA::$privateKey);
		$plaintext = $rsa->decrypt($encryText);
		return $plaintext;
	}
}
?>

<?php

//create keys
myRSA::createKeyPair(1024);

//Text to encrypt
$text = "A secret lies here, send the text via a secure mode";
echo 'Text : '.$text;

$secureText = myRSA::encryptText($text);
echo 'Encrypted : '.$secureText;

$decrypted_text =  myRSA::decryptText($secureText);
echo 'Decrypted Text : '.$decrypted_text;
?>

PHPSecLib API Documentation is available here.[4] A handy reference to check when you get stuck or need more info on methods.

[1] http://phpseclib.sourceforge.net/index.html

[2] https://en.wikipedia.org/wiki/MIT_License

[3] https://www.gnu.org/licenses/license-list.html#X11License

[4] https://api.phpseclib.org/master/

Think before calling an unknown number, you will be hacked ?

Interesting security advice is being circulated these days. It says;

Apparently “many are getting a missed call from the number +17675027697. Looks like a virus where calling back this number might hack your phone or something. Be Careful !

Can this be true?

When you got a missed call, you might call the number and check who the hell it is. Or at least you in return make another missed call. Can this act lead to a hacking of your mobile? Indeed NO, it is not possible. So you can rule out the risk of being hacked. In that context the message is a bloody hoax. But yes there is a BUT, there are some risks. In fact a social engineering attacks. Being more specific, a type of vishing[1].

Well first, the attackers can deceive you with a recording, imitating that you have reached to a lottery or a draw and you have won a grand prize (most probably some dollars) and then you will be directed through some menu options to select this and that and finally may ask for you credit card details (or some personal information such as social security number{NIC in SL} etc) and so on. Or else even it is possible to request your details such as email address via voice, so that the bot can record it and convert to text. There can be endless possibilities but the main motive is to collect your personal and/or financial information.

When you respond calling back the attacker, it get to know your phone number is real. That means he earns a real phone number. Real phone numbers are expensive than a real email. He can sell it for a good price in deep web. Advertisers or even hackers are interested in such info as they can flood you with advertisements or use social engineering to exploit more info from you. What if you provide your personal info such as age, city you are live in etc. A partially complete profile of you.

Other than that an attacker can do nothing. He cannot hack you via a call as there is no way to access your mobile phone OS or any other installed application via a phone call (unless you use such an app or an OS which enables such, surely not Android nor iOS). But if your mobile is infected with a virus that enables such functions, need not to mention that, you are in a grave. But in that case I dont think the attacker will use such a dumb technique to gain control. He can simply connect the phone via internet and access your mobile and check what you are doing via the phone’s camera. Sounds like a sci-fi movie scene but this is 100% practical and possible.

No party can charge you an extra amount (other than the standard tariffs) for the call you make, unless there is an pre-agreed agreement. Even the carrier itself cannot subscribe you to a service and charge you because you called a number. If such things in place you need to be informed once the call has been answered and seek your consent/ verification to move forward.

Finally, the message seems quite exaggerated. But better you refrain calling unknown numbers, doesnt matter local or foreign. Even you called back do not give any private information unless the person on the other side is verified, May be you are not going to provide any information but simply calling back the number and hanging the line (another missed call by you in that case) hints that your mobile number is real. You may be a target of a bot generating random phone numbers with miss calls and then try to check if the number is real.

Better you worry about above facts rather than worrying about getting your phone hacked.

Ref 1 : https://en.wikipedia.org/wiki/Voice_phishing

Time Zone Conversions (after Google lies)

Google is at my disposal, easy to use and pretty accurate. Hence I use Google frequently to check time in other countries and also use it pretty much to convert time. However once Day Light Saving (DST) has started the time conversion seems to be not correct,

For an example, the time difference is 3.5 hrs in CET to IST when DST is in effect. But Google still thinks the difference is 4.5 hrs.

google_search_results

Search Link

I prefer www.timeanddate.com which is one of the best tools to work with time zones. Time zone conversion is pretty handy, I would say it is pretty CooL.

Having said that, I also came across WolframAlpha.com which is handy and smart as well.

wolframalpha

Search Link

WolframAlpha is amazing, it comes with some useful tools.

wolframalpha_tools

I played with few and still exploring the other tools. Firefox add-on, Chrome extension are also available. Just give it a try. You wont get regret, I m pretty sure.

PS: found the following article when I google – Google Lies, pretty funny and interesting, have a look guys !

The Soptail

Recently I have came across a lavish cocktail mixture, of course I am writing this while enjoying a glass of the newly crafted beauty.

Ingredients:

  • whiskey – used Johnnie Walker Red Label
  • soursop juice
  • mango juice
  • and ice

Method:

Prepare raw soursop juice and raw mango juice. Blend those two together. Feel free to research the right portions. I am satisfied with soursop:mango to 5:1. Shake the juice base with some whiskey. Then fill the glass with ice and pour the mixture on top of it. Again it is upto you to decide the right portions. I settled with 3:1 to Juice base:whiskey.

I tested another version of this with a slight change. Instead shaking, add the juice base and whiskey to the glass and stir. This is having a good punch and a vibrant taste.

Feel free to check this and let me know your ideas !!!!

–composed with WordPress android app–

CAPTCHA with no $_SESSION

Due to the nature of the stateless behavior of HTTP, managing the current state of a connected user is a tricky scenario to handle in web site development or rather in web application development.

Few solutions are in place already and $_SESSION is one of the ways available in PHP. $_SESSION, the global array is not my favorite choice but it is handy. The sever based session management approach is not 100% reliable but it would do the work in most of the cases.

On the other hand, distinguishing user inputs versus inputs from malicious bots seems quite challenging these days. Simple tricks such as “honeypot” are quite old and easy to overcome, of course bots are now capable enough to skip “honeypots” without much effort. Then comes much promising solutions such as Google’s new invention, reCAPTCHA where a sophisticated techniques can identified the origin of the inputs blocking spams on your site, web application etc.

However life is not that easy, there are plenty of scenarios where we need to come up with our own strategy to deal with these inputs. If you cannot use reCAPTCHA or any other 3rd party CAPTCHA solution then the best would be implementing one of your own. This is the riskiest but there can be instances that this is the only way forward. I was in such a situation few months back and I though of sharing how I overcame it.

Avoiding $_SESSION

It is not hard to find plenty of tutorials to follow, implementing simple CAPTCHA verification in PHP. Almost every solution is based on $_SESSION, using server based sessions, a global array in PHP. This is easy and simple. Few lines of code would do the trick. As same as the way mentioned in this article. I am not a fan of server based sessions therefore I wanted to skip it.

In this post I am trying to explain how I solved the stateless issue without using server based sessions.

Breaking the Problem

The main issue that we need to solve is identifying the legitimate requests/ inputs and filter out the rest. In order to achieve this, when the relevant input form has been requested by a client, the server adds an image which is a human readable text. Bots may not be able to identify what is in it. Then the user inputs the code and sends the request to the server. As it is not possible to include the verification code in the client side request, the server doesn’t know what has been sent earlier. That is where server based sessions comes for the rescue. It is possible to store the verification code in a session variable.  Then when the user has submitted the form, the server can simply checks if the entered verification code value matches the value in the session. If so it is a human, test passes. Since we are trying to omit using server based sessions, we need to come up with a way to identify what has been sent earlier.

Solution

Step 1

Following is a typical code snippet (captcha.php) to create the CAPTCHA image. It is pretty straight forward and it can be seen that the verification code has been assigned to the session variable, $_SESSION[‘rand_code’] = $string;

<?php
session_start();

$string = '';

for ($i = 0; $i < 5; $i++) {     // this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122)); }   
$_SESSION['rand_code'] = $string;   
$dir = 'fonts/';   
$image = imagecreatetruecolor(170, 60); 
$black = imagecolorallocate($image, 0, 0, 0); 
$color = imagecolorallocate($image, 200, 100, 90); // red 
$white = imagecolorallocate($image, 255, 255, 255);   imagefilledrectangle($image,0,0,399,99,$white); 
imagettftext ($image, 30, 0, 10, 40, $color, $dir."arial.ttf", $_SESSION['random_code']);   
header("Content-type: image/png"); 
imagepng($image); 
?>

Following shows how it has been included in the HTML, client side.

<form action="<?php echo $_SERVER['PHP_SELF']; ?>
" enctype="multipart/form-data" method="post"><input name="name" type="text" />

<input name="email" type="text" />

<textarea name="message"></textarea>

<img src="captcha.php" />

<input name="code" type="text" />

<input name="submit" type="reset" value="Send" />
</form>

When analyzing the HTML code, you will soon realize that the code can be exploited simply with a Cross Site Scripting (XSS) attack as it barely uses $_SERVER[‘PHP_SELF’] in form action. I will not be focusing on that since I am not going to use sessions here. Following is the modified prototype version.

Step 2

I have changed the client side code as follow. Notice that a hidden filed has been introduced. A randomly generated number with hash coded act as the reference id here. The reference has been passed when creating the CAPTCHA image and also it gets submitted when the user submits the form.

<?PHP
require_once 'dataBaseConnection.php';
<form action="verify.php" enctype="multipart/form-data" method="post">
Name: <input name="name" type="text" />

Email <input name="email" type="text" />

Message
<textarea name="message"></textarea>

<!--?PHP   $captchaId = sha1(rand(1000000,9999999).time());  dataBaseConnection::registerReference($captchaId);  $path='captcha.php?ref='.$captchaId;   ?--> <img src=""<?PHP" /> "/>
Enter the above code
<input name="c_id" type="hidden" value="<?PHP echo $captchaId; ?>" />

<input name="code" type="text" />

<input name="submit" type="submit" value="Send" />

and then the captcha.php has been modified too.

<?php
$string = '';
$refCode = '';

if(isset($_GET['ref']))
{
$refCode = $_GET['ref'];
}else{
die('<error>NO REF CODE FOUND !</error>');
}

for ($i = 0; $i < 8; $i++)
{
// this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122));
}

$dir = 'fonts/';

$image = imagecreatetruecolor(170, 60);
$black = imagecolorallocate($image, 0, 0, 0);
$color = imagecolorallocate($image, 10, 10, 10); // red
$invColor = imagecolorallocate($image, 200, 200, 200); // invisible_ink
$white = imagecolorallocate($image, 255, 255, 255);

imagefilledrectangle($image,0,0,399,99,$white);
for($i=0; $i<100; $i++) 
{ 
imagettftext ($image, 20, rand(0,10), 0, $i*10, $invColor, $dir."ts.ttf", 'xxxxxxxxxxxxxxxxxxxxxxxxx'); 
} 
imagettftext ($image, 30, 2, 10, 40, $color, $dir."ts.ttf", $string);
header("Content-type: image/png"); 
imagepng($image); 
require_once 'dataBaseConnection.php'; dataBaseConnection::addVerificationCode($refCode, $string); //store the reference and the code in the database 
?>

The static methods dataBaseConnection::registerReference stores the reference code which will later be an input to captcha.php. The system automatically logs the timestamp and set the status of the record to ‘CREATED’. Then in the captcha.php file static method dataBaseConnection::addVerificationCode adds the generated verification code to the relevant reference .

Step 3

Then comes the verify.php code which validates the entered code against the code in the database.

<?php require_once 'dataBaseConnection.php'; if(isset($_POST['submit']))   {  	$enteredCode=trim($_POST['code']);  	$referenceCode=trim($_POST['c_id']);     $dataSet = dataBaseConnection::getCode($referenceCode);     $timeTaken = time() - $dataSet['pvt_created_date'];     if($timeTaken>$dataSet['pvt_life_time'] || $dataSet['pvt_captcha_status']!='CREATED')
    {
    	die('expired code');
    }

    //var_dump($referenceCode); die($enteredCode);
	if($enteredCode==$dataSet['str_verification_code'])
	{
		dataBaseConnection::updateCode($referenceCode,'VERIFIED');
		echo 'verified';//this is a human
		//Process the input as this is a legit request
	}else{
		dataBaseConnection::updateCode($referenceCode);
		echo 'not verified';//most probably not a human
	}
}
?>

If both codes match then the static method dataBaseConnection::updateCode changes the status of the verification code to ‘VERIFIED’ in the database while the status has been set to ‘USED’ for the verification code if they dont match. That expires the verification code and it will not be possible to use it again. Further there is a check to make sure that the code has not been expired too.

How secure this is

It is not difficult to train a bot to reading CAPTCHAs. Therefore to make this much stronger it is required to have an image with higher entropy.

Another weak point is, the reference code is getting exposed to the attacker. However there reference number has no relationship with the code. Therefore the attacker cannot predict the code by cracking the reference code. This is possible as we store the reference and the verification code in the database.

An attacker cannot use a brute force attack as the status of the verification code has been updated after an attempt has been made disregarding the results. So once tried the code is set to expired. Setting lifetime of the code can be used to limit the time available for the attacker to crack the image. In this case 300 seconds.

Further it is required to restrict direct access to captcha.php file from the outside, simply using .htaccess entry. Otherwise it is possible to carry out a Denial-of-service attack targeting the generation of the captcha image which in return could have lead to a database failure.

It is important to track client details but will discuss it in another post.

Conclusion

How to implement a captcha verification solution without using server based sessions has been discussed above. Complete source code can be found here. Please check it out and let me know any flaws you observe. This is a mere implementation of the concept and no other aspects were considered when developing the code and no proper testing has been carried out. Therefore if you are going to use it in your code please be careful unless you know what you are doing.

Finding MAC Address (MAC Filtering cont.)

One of my friends has read the article on MAC Filtering and inquired an easy way to find out the MAC addresses of the devices. This the easiest I came across so far.

You need to log into the admin panel of the router, find the place which shows the connected/ (or history of the connected devices). It gives the list of MAC addresses along with some identification. (Eg: in my routers home page it shows the device history with MAC addresses and an identification tag, it says AA:BB:CC:DD:EE:FF and iPhone, so I figured out it is my wife’s. The dumbest thing in my home, ohhh no not the wife I meant, but the iPhone)

Get the list and add it to the MAC filter. It is simple.

Any better idea? Please comment !