Wednesday, January 28, 2009

PHP Cryptography

This is a follow up to my investigation in cryptography. If you read my previous Java Cryptography blog, then you already know that I build this PHP Encryption API to test against the Java Encryption API. If you just jump right into this blog, I'll make a long story short. I had to do some encryption/decryption testing. That's how this API got generated.

Here's what I learn. PHP provides a very powerful and easy to develop encryption mechanism using MD5, Standard DES, Extended DES, and Blowfish security algorithm. PHP has a built in encryption mechanism that will allow you to encrypt string using any of the previous mentioned algorithm and return a hash value (encrypted data). This makes the task of encrypting and comparing password very easy. Best way to learn is by downloading the source code and try it out. Man, the time already passed 11:30PM, and I have to get up early tomorrow and goto work. I'll cut this blog short and will tag information to it tomorrow night.

Source code (Encryption API): Encryption.php


<?php

/********************************
* A class for illustrating MD5, Standard DES, Extended DES, and Blowfish encryption process and comparing encryption data
*
* Encryption.php
*
* @version 0.1 27 January 2009
* @author Jay Suttiruttana
*
* Interpreter: PHP v5
* Development Platform: Linux 32 bits Kernel 2.6.22.19-0.1 / X86-64
*
* license: GNU LGPL
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*/

class Encryption{
//define method attributes
private $CRYPT_TYPE_MD5 = '$1$ABCDEFGH$'; //8 characters salt w/ $1$...$
private $CRYPT_TYPE_STD_DES = 'AB'; //2 characters salt
private $CRYPT_TYPE_EXT_DES = '12345678'; //8 character salt
private $CRYPT_TYPE_BLOWFISH = '$2$ABCDEFGHIJKLMNOP$'; //16 characters salt w/ $2$...$

//constructor
public function Encryption(){
}

//function encrypt password(username, password)
public function encryptPassword($uid, $pwd){
$completionFlag = false;
// TODO: create an insert to system db or write to flat file on user info

// SQL statement:
// insert $DB_MD5, $DB_DES_STD,$DB_DES_EXT, $DB_BLOWFISH to
// Client_Information where username = $uid;

$DB_PWD = crypt($pwd, $this->CRYPT_TYPE_MD5)."|".
crypt($pwd, $this->CRYPT_TYPE_STD_DES)."|".
crypt($pwd, $this->CRYPT_TYPE_EXT_DES)."|".
crypt($pwd, $this->CRYPT_TYPE_BLOWFISH);

//filename is the user ID.
if($this->generateUserPWDFile($uid, $DB_PWD)){
$completionFlag = true;
}
return $completionFlag;
}

//function authenticateUser_All(username, pasword)
//check all encryption.
public function authenticateUser_All($uid, $pwd){
$authenticateFlag = false;

//open password file for reading
$fileHandle = fopen($uid, 'r');
$data = fread($fileHandle, filesize($uid));
fclose($fileHandle);

//Parse string $data using regex with | as delimeter
//and assign value to homeULR, logoFile, and copyright
$pData = spliti ("\|", $data);
$DB_MD5 = $pData[0];
$DB_DES_STD = $pData[1];
$DB_DES_EXT = $pData[2];
$DB_BLOWFISH = $pData[3];

if (($this->validateMD5($pwd, $DB_MD5)) &&
($this->validateSTD_DES($pwd, $DB_DES_STD)) &&
($this->validateSTD_EXT($pwd, $DB_DES_EXT)) &&
($this->validateBlowfish($pwd, $DB_BLOWFISH))){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with MD5 encryption
private function validateMD5($pwd, $cPwd){
$authenticateFlag = false;


if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_MD5)){
$authenticateFlag = true;
}
return $authenticateFlag;
}


//validate password with Standard DES encryption
private function validateSTD_DES($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_STD_DES)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with Extended DES encryption
private function validateSTD_EXT($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_EXT_DES)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//validate password with Blowfish encryption
private function validateBlowfish($pwd, $cPwd){
$authenticateFlag = false;

if ($cPwd == crypt($pwd, $this->CRYPT_TYPE_BLOWFISH)){
$authenticateFlag = true;
}
return $authenticateFlag;
}

//write to file
private function generateUserPWDFile($filename, $value){
//create password file and write encrypted password to file
$fileHandle = fopen($filename, 'w') or die("can't open file");
fwrite($fileHandle, $value);
fclose($fileHandle);

return true;
}
}

?>


Source code for testing Encryption API: testEncryption.php


<?php
/**
* testEncryption.php
*
* Example 1: Test encryption. This will encrypt password and create a file.
* % php testEncryption.php jay test e
*
* Example 2: Test authentication. This will authenticate username & password.
* % php testEncryption.php jay test a
*
* @version 0.1 27 January 2009
* @author Jay Suttiruttana
*
* Interpreter: PHP v5
* Development Platform: Linux 32 bits Kernel 2.6.22.19-0.1 / X86-64
*
* license: GNU LGPL
*/

require_once("Encryption.php");

if (($argc != 4) || ($argc > 4)) {
print "Missing required information... {username} {password} {e/a}\n";
exit();
}
else {
$uid = $argv[1];
$pwd = $argv[2];
$test = $argv[3];
}

$enc = new Encryption();

switch ($test){
case 'e'://Test encrypted file creation
//comment out if/else logic below to test file creation
echo "Encrypting password for uid:".$uid."\n";
if($enc->encryptPassword($uid,$pwd)){
echo "success...\n";
}
else {
echo "fail...\n";
}
break;

case 'a'://Test authentication
//comment out if/else logic below to test authentication
echo "Authenticating user:".$uid."\n";
if($enc->authenticateUser_All($uid,$pwd)){
print "[access granted]\n";
}
else {
print "[access denied]\n";
}
break;
}

?>


Sample output:

First, I executed (e)ncryption for my password "test". This forces the API to create
a flat file containing encrypted password. Then I executed (a)uthentication to
authenticate my username and password, which resulted in "access granted". Then I
executed another authentication using uppercase "TEST", which resulted in "access
denied". Finanlly, I view the content of my password file using the cat command.

% php testEncryption.php jay test e
Encrypting password for uid:jay
success...

% php testEncryption.php jay test a
Authenticating user:jay
[access granted]

% php testEncryption.php jay TEST a
Authenticating user:jay
[access denied]

% cat jay
$1$ABCDEFGH$b1FW49h9UTi.E6xXyTsWl0|ABwOg1D2JDxIQ|126D8rSh5sjUE|*0

No comments:

Post a Comment