I'm going to be implementing a PHP/mySQL
setup to store credit card information.
It seems like AES_ENCRYPT/AES_DECRYPT
is the way to go,
but I'm still confused on one point:
How do I keep the encryption key secure?
Hardwiring it into my PHP scripts (which will live on the same server as the db) seems like a major security hole.
What's the "best practice" solution here?
You should think long and hard about whether you REALLY need to keep the CC#. If you don't have a great reason, DON'T! Every other week you hear about some company being compromised and CC#'s being stolen. All these companies made a fatal flaw - they kept too much information. Keep the CC# until the transaction clears. After that, delete it.
As far as securing the server, the best course of action is to secure the hardware and use the internal system socket to MySQL, and make sure to block any network access to the MySQL server. Make sure you're using both your system permissions and the MySQL permissions to allow as little access as needed. For some scripts, you might consider write-only authentication. There's really no encryption method that will be foolproof (as you will always need to decrypt, and thus must store the key). This is not to say you shouldn't - you can store your key in one location and if you detect system compromise you can destroy the file and render the data useless.
MySQL, there is six easy steps you can do to secure your sensitive data.
Step 1: Remove wildcards in the grant tables
Step 2: Require the use of secure passwords
Note: Use the MySQL “--secure-auth” option to prevent the use of older, less secure MySQL password formats.
Step 3: Check the permissions of configuration files
Step 4: Encrypt client-server transmissions
Step 5: Disable remote access
Step 6: Actively monitor the MySQL access log
Security Tools
I agree, but don't the cc if you don't need too. But if you really have too, make sure the file that have it is not accessible on the web. You can write a binary that would return the key. This way it's not store in clear text. But if your server is compromise it's still easy to get it.
the security you need depends on your application. for example, if the only time the cc# will be used is when the user is logged in (thin online store type scenario), then you can encrypt the cc# with the a hash of the user's plain-text password, a per-user salt, and a dedicated cc# salt. do not store this value permanently.
since you're not storing this value, the only time you can get this value is when the user enters their password to log in. just make sure you have good session expiration and garbage collection policies in place.
if this situation does not apply to you, please describe your situation in more detail so we can provide a more appropriate answer.