views:

66

answers:

2

I'm working on a very small form that accepts credit card numbers, which will be cleaned out shortly thereafter. For the time they exist in the database, I'd like them to exist in a comfortable state of encryption. Unfortunately, in my many years of web-development, programming, and database-development, I've not once had the opportunity to educate myself in the area of encryption.

Is there are relatively easy-to-implement method of encrypting credit card numbers that I can implement quickly? A set of functions, class, anything at all that will get the job done, and done well? I am taking this opportunity to educate myself on the issue, but due to time-sensitivity, more than just a nudge in the right direction is requested.

Language: PHP / Storage: MySQL

+3  A: 

One of the best ways is to simply use MySQL for the encryption / decryption. See these functions:

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html

However, keep in mind that while this will protect you against people who may find a way to read your database, it will not protect against someone who owns the server. That's because the decryption key is present on the server.

All in all, it's a huge boost. True security would come from public key encryption and offline decryption with a secure private key (eg. different server).


As an example:

INSERT INTO BillingInfo 
SET CCard = AES_ENCRYPT('4111...', 'super-secret-key')
...

and

SELECT 
AES_DECRYPT(CCard, 'super-secret-key') 
...

The specific function is documented here:
http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_aes-encrypt

For more information on AES, please see:
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard


For maximum security in your environment, I suggest you store the key in a PHP constant. It's less likely to get divulged at runtime that way (minor detail).

gahooa
Do you have any suggestion as to which one of these methods I should pursue?
Jonathan Sampson
I'd look at AES.
bobince
As bobince said, look at `AES_ENCRYPT()`. See the edit to the question for an example.
gahooa
I hope that with "PHP constant" you mean a const variable and not a hardcoded key?? Since using hardcoded keys is really NOT the way to go!! Storing data encrypted with hardcoded keys is almost as bad as no encryption at all. Consider a decent key management solution.
Henri
@Henri: Most PHP developers would not even bother to consider encryption in the first place. A key stored in a PHP file is better than no encryption. But your suggestion is even better. Can you elaborate on possibilities there? Thanks!
gahooa
A: 

It's less ‘easy’, but if your application doesn't need to read back the stored credit cards (ie. they're only read by another part of the system), you could use public key crypto to encrypt the information in such a way that your own webapp cannot decrypt it.

That way, even if an attacker gains access both to the database and your webapp's own scripts, they still don't get the card data. Only the other, card-handling part of the system (which is presumably more locked down against attack) can decrypt them.

You'd start with the openssl_public_encrypt function. example use

bobince