Rayhan’s blog (raynux.com)

Rayhan’s Personal Web Blog Site

Entries Comments


RayCrypt – PHP Class for Quick Two Way Encryption and Decryption

6 November, 2010 (19:26) | PHP, PHP Classes, programming, Reference, web security

Tags: , , , , , , , , ,


RayCrypt, A simple and easy PHP class for two way encryption and decryption with multiple configurations and plug and play features.

Sometimes two way encryption is very much important when it comes in storing credential information. Credit Card, Bank account information, digital signature etc are very important information of user and strongly discouraged to store in plain text. These data should always be stored in encrypted format. PCI has a very strict guideline and policy for storing Credit Card Information in database or file.

This class is very handy to solve this type of situation.

Features:

- Simple & Easy to use from anywhere in your application with a single line of code.
- Easily configurable & can work without any configuration.
- Support multiple salt configurations
- Requires PHP Mcrypt library installed
- Static method for encryption and decryption
- Light Weight

Method:

- RayCrypt::encrypt();
- RayCrypt::decrypt();
- RayCrypt::config();
- RayCrypt::padString();

Class:

File: raycrypt.php

<?php
/**
 * Two way Encryption and Decryption Class.
 *
 * Suitable for storing credential information like credit card, bank account information into the database
 *
 * PHP version 5+
 * - require Mcrypt library installed
 *
 * @package     raynux
 * @subpackage  raynux.labs.crypt
 * @version     1.0
 * @author	Md. Rayhan Chowdhury
 * @license     MIT License http://www.opensource.org/licenses/mit-license.php
 */

/**
 * Encrypt & Decrypt Using PHP MCrypt Library
 *
 * @package     raynux
 * @subpackage  raynux.labs.crypt
 * @author      Md. Rayhan Chowdhury
 */
class RayCrypt{

    /**
     * RayCrypt Instances
     *
     * @var RayCrypt
     */
    protected static $_instances = array();

    /**
     * Secret Salt generated from the key
     *
     * @var string
     */
    protected $_secretKey;

    /**
     * Default Configuration Array
     *
     * @var array
     */
    protected $_defaults = array(
                                    'returnPlainText' => true,
                                    'salt' => '7$e4!158f6$%#be533.!@a066!#35428^#%&$*&faa91:!982*#!e07'
                                );

    /**
     * Hold Run-time configuration
     *
     * @var array
     */
    protected $_configs = array();

    /**
     * Class Constructor
     *
     * @param array $options
     */
    private function __construct($options = null) {
        $this->_setConfig($options);
    }

    /**
     * Get Instance of RayCrypt
     *
     * @param string $configName
     * @param array $options
     * @return RayCrypt
     */
    private static function &_getInstance($configName = null, $options = null) {

        if (empty($configName)) {
            $configName = 'default';
        }

        if (empty(self::$_instances[$configName])) {
            self::$_instances[$configName] = new self($options);
        }

        return self::$_instances[$configName];
    }

    /**
     * Configure the class instance
     *
     * @param array $options  array('salt' => '', 'returnPlainText' => true)
     * @return RayCrypt
     */
    protected function &_setConfig($options = null) {

        if (empty($options) || !is_array($options)) {
            $options = array();
        }

        $this->_configs = array_merge($this->_defaults, $options);

        if (!empty($this->_configs['salt'])) {
            $this->_setSecretKey($this->_configs['salt']);
        }

        return $this;
    }

    /**
     * Set secret salt for encryption algorithm
     * @param string $key
     * @return RayCrypt
     * @access protected
     */
    protected function &_setSecretKey($key) {
        $this->_secretKey = md5(substr(sha1($key), 0, 32));
        return $this;
    }

    /**
     *
     * @param  $configName
     * @param  $options
     */
    public static function config($configName, $options = null) {
        $_this = self::_getInstance($configName, $options);
    }

    /**
     * Encrypt using Mcrypt PHP Library
     *
     * @param string $value
     * @param string $configName
     * @return string
     * @access public
     * @static
     */
    public static function encrypt($value, $configName = null) {

        $_this = self::_getInstance($configName);
        $key = $_this->_secretKey;

        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $encryped = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv);
        if (!empty($_this->_configs['returnPlainText'])) {
            $encryped = base64_encode($encryped);
        }

        return $encryped;
    }

    /**
     * Decrypt Using Mcrypt
     *
     * @param string $value
     * @param string $configName
     * @return string
     * @access public
     * @static
     */
    public static function decrypt($value, $configName = null) {
        $_this = self::_getInstance($configName);
        $key = $_this->_secretKey;

        if (!empty($_this->_configs['returnPlainText'])) {
            $value = base64_decode($value);
        }

        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_ECB, $iv), "\0\4");
    }

    /**
     * Masks Important Information Padding String
     *
     * helpful in displaying a part of credit card information like
     * 01234567890 will result xxxxxxx7890
     *
     * @param string $string
     * @param integer $length specify negative length to mask from backward
     * @param mask character $maskCharacter
     * @return string
     * @access public
     * @static
     */
    public static function padString($string, $length, $maskCharacter = 'X') {
        $maskString = substr($string, 0, $length);
        $maskString = preg_replace('(.)', $maskCharacter, $maskString);
        $string = $maskString . substr($string, $length);
        return $string;
    }

}

?>

Usage Example: some quick examples are given below to introduce you with the class and it’s methods.

<?php
/**
 * RayCrypt Example File
 */

/**
 * Load RayCrypt Library
 */
include_once 'raycrypt.php';

/**
 * Basic debug function
 *
 * @param mixed $value
 */
function dump ($value) {
    printf('<pre>%s</pre>', var_export($value, true));
};

/**
 * Use RayCrypt without any configuration, it uses default configuration
 */
$data = 'My important data';
$encrypted = RayCrypt::encrypt($data);
$decrypted = RayCrypt::decrypt($encrypted);
dump(array('data' => $data, 'encrypted' => $encrypted, 'decrypted' => $decrypted));

/**
 * Output
 array (
  'data' => 'My important data',
  'encrypted' => 'JBtn3msE0QIAei/v9oHP5nW2xasbdSeVhAb4nPXqiUA=',
  'decrypted' => 'My important data',
)
 */

/**
 * Use RayCrypt with a separate configuration salt for creditCard information
 */
RayCrypt::config('creditCard', array('salt' => 'jdfjsddfsdf!$#fjsdkjfsdfi7*@(@sdhf'));
$data = '01234567890';
$encrypted = RayCrypt::encrypt($data, 'creditCard');
$decrypted = RayCrypt::decrypt($encrypted, 'creditCard');
dump(array('data' => $data, 'encrypted' => $encrypted, 'decrypted' => $decrypted));

/**
 * Output
array (
  'data' => '01234567890',
  'encrypted' => 'E9FO62vScqmObOlIXso70Hx8JpEqzVOiac8yuk3/4yM=',
  'decrypted' => '01234567890',
)
 */

/**
 * Use RayCrypt with a another configuration for bank information
 */
RayCrypt::config('bank', array('salt' => 'Nothing wrong'));
$data = '884585847';
$encrypted = RayCrypt::encrypt($data, 'bank');
$decrypted = RayCrypt::decrypt($encrypted, 'bank');
dump(array('data' => $data, 'encrypted' => $encrypted, 'decrypted' => $decrypted));

/**
 * Output
array (
  'data' => '884585847',
  'encrypted' => 'BnDAjNJq/ZrwEKT9yLVFEVZO0b4/uu2AWRGVhX3mVRw=',
  'decrypted' => '884585847',
)
 */

dump(RayCrypt::padString('0123456789', -4)); // output 'XXXXXX6789'

?>

Please let me know if you find this class helpful for you..

«

  »

Comments

Comment from shanewaj
Time: December 22, 2010, 5:10 am

thanks for nice php class … saved lots of time for me …

Comment from Brendan
Time: March 18, 2011, 12:56 am

I’ve noticed all of the encrypted values end with an ‘=’ sign. Any idea how to change this or set the class to not include that within the encrypted password?

I’m having issues and I believe the trailing ‘=’ is preventing my SQL queries from running.. Any input is appreciated

Comment from rayhan
Time: March 18, 2011, 1:06 am

The ‘=’ sign comes from base64_decode function and not common in all scenario. I am afraid you can’t change this, but why not escape your SQL query properly. It should never be a problem if your SQL query is escaped properly.

Comment from Praxus
Time: August 30, 2011, 4:46 pm

Thanks, I’m using it without any config and it’s excellent.

Comment from Sumon @ WPCypher
Time: December 17, 2011, 6:17 pm

Nice and useful class for encryption solution. Thanks! Looking forward to try it…

Write a comment