For every application, you're faced with the challenge of storing login data in a secured manner such that it cannot be manipulated or modified in any way.

But how can you achieve this in PHP? I'm giong to run through the main features of the PHP Mcrypt library and how you can use them on all of your projects.

Creating our Security Class

To begin, we're going to create our class that will store all our associated encryption functions and place them under a library helper namespace:

namespace LibraryHelper;
/**
 * This is our Security class which we will use to encrypt and decrpyt
 * our data across our application.
 *
 * @author Lewis Theobald
 * @version 1.0.0
*/
class Security {
	/**
         * var: Stores our generated cipher key.
        */
	private static $cipherKey = '';
	/**
         * var: Stores our secret cipher keys which we use to encrypt our data.
         * They should both be 32 characters in length of random characters.
        */
	private static $cipherKeys = array('', '');
}

I'm going to discuss two alternative techniques to encrypt your data and provide the methods to decrypt the data at the same time. From my own personal experience, I've had different levels that I want to secure my data, from database passwords to storing cookie content and sessions. So the first example I consider is a quick encryption algorithm that encrypts data under the 256-bit Rijandael standard in CBC mode (Why do we use CBC over ECB, check out ECB vs CBC Encryption. Also, using this version supports comptability with C/C++ language PKCS7 encryption).

Generating a Cipher Key

We need a method to generate a random encryption key and return the key matching a specific length. For example, we can encrypt with a 32, 64 or 128 cipher key:

private static function getEncryptionKey($keySize) {
	# Get our keys
	$key1 = md5(self::$cipherKeys[0]);
	$key2 = md5(self::$cipherKeys[1]);
	# Create unique key
	$key = substr($key1, 0, $keySize/2) . substr(strtoupper($key2), (round(strlen($key2) / 2)), $keySize/2);	
	$key = substr($key.$key1.$key2.strtoupper($key1), 0, $keySize);
	# Return key		
	return $key;
}

Encryption & Decryption Methods

The method above generates a new cipher key which is unique every time so that there is no way to determine the encryption key used. We now need a method to encrypt and decrypt our data:

/**
 * quickEncrypt: Given the plaintext, generate a cipher key
 * and encrypt the data. We further encrypt with base64 to maintain consistency
 * of our data across different platforms and encoding environments.
 *
 * @param $clearText- The plaintext data
 * @return string - The encrypted data
*/	
private static function quickEncrypt($clearText) {
	# Get keysize and key		
	if(empty(self::$cipherKey)) {
		# Get the cipher key
		self::$cipherKey = self::getEncryptionKey(32);
	}
	# Create our IV key:
	$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
	$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
	# Get our encrypted text
	$cipherText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::$cipherKey, $clearText, MCRYPT_MODE_CBC, $iv);
	# Return our string
	return trim(base64_encode($cipherText));
}
/**
 * quickDecrypt: Given the encrypted text, generate a cipher key
 * and decrypt into plaintext.
 *
 * @param $value - The encrypted data
 * @return string - Our plaintext data
*/	
private static function quickDecrypt($value) {
	# Decode our string
	$cipherText = base64_decode($value);
	# Get keysize and key		
	if(empty(self::$cipherKey)) {
		# Get the cipher key
		self::$cipherKey = self::getEncryptionKey(32);
	}
	# Verify our IV size:
	$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
	$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
	# Decrypt the string
	$clearText = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::$cipherKey, $cipherText, MCRYPT_MODE_CBC, $iv);		
	# Return the clearText
	return trim($clearText);
}

Encrypting & Decrypting Data

Now we've set everything up, if we have a login script, we can simply store the encrypted data in the cookie and then decode it on the fly to get the user:

namespace ApplicationModule;
use LibraryHelperSecurity;
/**
 * Login: This is just a simple class setup showing you how to
 * load your namespace and pull in the Security class we've
 * put together so far.
 *
 * @author Lewis Theobald
*/
class Login {
	/**
	 * processLogin: Assuming, we have POST and at this point it has been
	 * validated.
	 *
	 * This method assumes we have a $userID (unique value for the user) and
	 * a $uniqueKey which acts as a login key for our active session.
	*/
	public function processLogin() {
		$encrypted = Security::quickEncrypt($userID.'-'.$uniqueKey);
		$decrypted = Security::quickDecrypt($encrypted);
	}
}

In the next addition to this tutorial, I'll expand on more complex algorithms and variations of AES (Advanced Encryption Standard) that PHP provides and how to multi-parse and encrypt data using md5 (not recommended due to its known collision weakness), SHA-256 and SHA-512.

Have you used any encryption in PHP before or used our code above? Let me know your comments by mentioning #ALJTMedia on Twitter or leave a comment on our FacebookGoogle+ or LinkedIn page.

Other Resources

0
Ignite your brand, utilise user-generated content no matter where you or your audience are ›