Tuesday, July 14, 2009

PHP GD: Creating a security captcha in PHP

I was working on an application yesterday when I had to write a captcha security check on the form. So I came up with the following script to generate an image with random code. The script will also rotate the code a little in the image and randomize the position of the code on the image. a random background will also be selected (random background image should be 100px by 30px).

<?php
session_start();

// note that $_GET['k'] is a static key that you can enter when getting the image.
// generate the key and store into session
$_SESSION['captchasecurity'] = md5(mt_rand().time().$session_hash).$session_hash.md5($_GET['k'].mt_rand());
// create a shorter key for display
$key = dechex(crc32($_SESSION['captchasecurity']));

// disable the client side caching
header('Content-type: image/png');
header('Cache-Control: max-age=0');
header('Expires: '.gmdate('r',time()-3600*24*365));
header('Pragma:');

// randomize the background image
$r = mt_rand(0,3);
$captcha = imagecreatefrompng('img/captcha'.$r.'.png');

$cl = mt_rand(0,50);
$c = imagecolorallocate($captcha, $cl, $cl, $cl);
$line = imagecolorallocate($captcha,233,239,239);

$txtx = imagefontwidth(5) * strlen($key) +10;
$txty = imagefontheight(5);

$timg1 = imagecreate($txtx,$txtx);
$ba = imagecolorallocatealpha($timg1,0, 0, 0,127);
imagefilledrectangle($timg1, 0, 0, $txtx, $txtx, $ba);
imagesavealpha($timg1, true);

$tc = imagecolorallocate($timg1, $cl, $cl, $cl);
imagestring($timg1, 5, 0, $txtx/2 - $txty/2, $key, $tc);

$tca = imagecolorallocatealpha($timg1, 255, 255, 255,127);
$timg = imagerotate($timg1, mt_rand(-5,5), $tca);
imagesavealpha($timg, true);
imagecopy($captcha, $timg, mt_rand(2,22), mt_rand(3,6), 0, $txtx/2 - $txty/2, $txtx, $txtx);

// output the captcha image
imagepng($captcha);

// free up memory
imagedestroy($timg);imagedestroy($timg1);
imagedestroy($captcha);
?>


To check whether the code entered by the user against the one generated, simply do the following:
<?php

// case sensitive check. CRC32 hash is in low case.
if($_POST['captchacode'] != dechex(crc32($_SESSION['captchasecurity']))){
// the code is wrong
}else{
// code is correct.
}

?>


Get the full code on Pastebin: http://thephpcode.pastebin.com/f21c1ed80

Note that this captcha script has been tested to be successful on my localhost. I cannot guarantee 100% bot proof. You are advised to step up the security in your own application.

3 comments:

anirudha gupta said...

HeLLO PHP DEVELOPER
i want to write our blog for asp.net or mvc on anirudhagupta.blogspot.com
but i like your THEME
are you give me your theme
if yes then send me
anirudhakumar.gupta@gmail.com

Regards
Anirudha gupta
Studio 7

thephpdeveloper said...

Hi Anirudha

this blog theme is default from Blogger. You might want to check out its templates.

Cheers
Sam

mark zukenberg said...

wonderful......................creation of captcha which is secure using php...........useful info.............

captcha bypass