Quite a few people suggested gpg/hash or public key. If you do that (I wouldn't), be sure to include fluff before and after the number inside your signed message; A credit card has ~30 bit of randomness, and if you know the hashed/encrypted (even if salted) version of the hash, a hacker can just enumerate the credit card number to see if it comes out the same.<p>It's not just the credit card numbers that are valuable -- it's the combination of credit card number + billing address that are generally required to make a purchase. 30 bit enumeration can require just a few minutes (or even seconds) on modern CPUs and GPUs. So, if you do store them this way, fluff them front and back with random data that you ignore when decoding.<p>What would I do? Make sure the user has a password (Use HMAC/bcrypt to verify password; DO NOT STORE PASSWORD!); When the user logs in, derive key from password using a different HMAC with different salt, and store in memory/session vars only for as long as needed. Use <i>that</i> key to encrypt the credit card number with a symmetric cipher, e.g. AES; make sure to purge these keys from memory/session directory early and often.<p>Advantage: You don't have access to the credit card on record even if you (or a rogue employee) wants to. Active participation from user _required_ to get access to data. If your server is hacked, only credit cards used while a hacker has complete view of traffic are compromised, and not all data stored.<p>Even better: offload to payment processor and make it their problem.<p>Really.