Skip to content

Comment on Ask HN: Storing Credit Card Numbers

Comments

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.

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.

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 that 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.

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.

Even better: offload to payment processor and make it their problem.

Really.

I am writing code to use authorize.net's CIM.

Here's the problem.

I don't like taking more information than is needed from people. I don't intend to take CVN numbers, and I don't intend to take Street addresses. You don't need them. All you need is a zip code for verification. I know people that run telephone chat lines. They only take zip codes, because people are typing everything into their telephones. No letters allowed.

Also, you'll note that 37 signals only takes a zip code. No CVN, no street address.

So, I log into my Authorize.net account, go to the virtual terminal, enter a transaction with only zip code verification. It works. No problem.

I go to their CIM panel, try to enter the same information. They tell me I need street address. Authorize.net tech support is extremely unhelpful, telling me to talk to Visa, ignoring that they allowed the exact same transaction through another area of their site.

So, I'm paying $25 a month for CIM, for the privelege of being forced to make my users life unnecessarily complicated. I have a problem with that.

If I can safely store those numbers without CIM, I intend to do so.

Well then, the method I described earlier would work for you; Exposure is limited to clients actually giving their passwords and/or using the credit cards _while the system is compromised_ ; It mitigates the risk that you keep hearing about in breaches, of _all_ accounts being exposed.

And just remember, that by storing those numbers locally, you're also taking potential liability for things that go wrong. To assess how much that is in cash, call a few insurance companies and ask them to give you a quote. Assume they have 25% markup on the real cost; That's how much you are "paying", although you are not doing it out-of-pocket (Though, in a catastrophic event, you _will_ be paying a lot)

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.