One of the issues with working in the software-as-a-service industry is that credit card numbers often have to be stored locally in a database. Keeping it on file with your payment gateway alone has a few limitations. The business folks may request storage for various reasons such as:
- Recurring subscriptions (often with variable amounts).
- Customers wanting to keep their card on file for future purchases.
- Transactional based software providers (such as cloud providers).
- Customer service wanting to verify the card on file with a customer.
- Managers wanting to authorize certain charges for employees.
When storing information as confidential as credit card data, even though it’s behind multiple passwords and buried in a database, it should be encrypted. PHP’s mcrypt library is ideal for this, using a cipher like MCRYPT_RIJNDAEL_256 (AES 128-bit) to encode 32 bytes of data (ideal for a card number and expiration). If you’re anything like me, developing a home grown solution means:
- Researching the various encryption ciphers.
- Looking into legal requirements.
- Re-reading PHP’s mcrypt function reference.
- Write a class or extend one with methods to provide encryption and decryption, generating IVs and such.
- Working with your project’s ORM or database libraries to implement the new class or methods for encryption.
- Build a testing strategy to ensure everything works and continues to work with future development.
I’d prefer not to do this with every implementation, so I decided to write a class called CreditCardFreezer. CreditCardFreezer is a PHP class which automates the storage and retrieval of encrypted credit card information to and from a database.
Although there are plenty of classes and packages (such as those in the Zend framework) for validating credit card numbers or interfacing with payment gateways, I was hard pressed to find anything that deals with encryption and storage of the secure data. With CreditCardFreezer, it’s as simple as:
$obj = new CreditCardFreezer;
$obj->number = '1234-1234-1234-1234';
$encrypted = $obj->setPassKey('super secret')
->get('number', true); // 'ViSxj3...'
// Store $encrypted into your database
$obj = new CreditCardFreezer;
$number = $obj->set('number', $encrypted, true)
->get('number');
echo $number; // 1234123412341234
CreditCardFreezer implements both a fluent interface for method chaining as well as an object-based one (shown above) which should be familiar for those who use an ORM like Doctrine. A complete documentation on the usage and syntax can be found here.
CreditCardFreezer is open source and PHPUnit tested. It’s released under the BSD license, so you’re free to use it as you like. More information can be found on my Github project page.
Some of the features it currently includes are:
- AES 128-bit encryption through PHP’s MCRYPT_RIJNDAEL_256 cipher.
- CFB mode for random IV generation upon every encryption to prevent patterns in the output.
- Numerous methods for storing and accessing various attributes used with credit card transactions, including secure attributes like card numbers and unsecured attributes like names and addresses.
- PDO class which can be used to implement ORM-like functionality to directly store and retrieve data from a database connection (and even create the schema).
- PHPUnit tested to ensure it works now and after future development.
More features to come such as direct Authorize.net and Paypal integration. Your feedback and any ideas or contributions are always welcome, just leave a comment or email me at me [at] andrewkandels.com.


