56

Storing credit card information securely and legally is very difficult and should not be attempted. I have no intention of storing credit card data but I'm dying to figure out the following:

My credit card info is being stored on a server some where in the world. This data is (hopefully) not being stored on a merchant's server, but at some point it needs to be stored to verify and charge the account identified by merchant submitted data.

My question is this: if you were tasked with storing credit card data what encryption strategy would you use to secure the data on-disk? From what I can tell submitted credit card info is being checked more or less in real time. I doubt that any encryption key used to secure the data is being entered manually, so decryption is being done on the fly, which implies that the keys themselves are being stored on-disk. How would you secure your data and your keys in an automated system like this?

Community
  • 1
  • 1
leepowers
  • 37,828
  • 23
  • 98
  • 129
  • Instead of asking, we paid them to do it for us :) – Josh Stodola Mar 17 '10 at 20:58
  • +1 But I *do* find this question very interesting, as I asked it to myself a couple years ago as well! – Josh Stodola Mar 17 '10 at 20:59
  • 1
    I just read this. It sounded like a conspiratorial whisper. "Hey, guys, someone is storing credit card data...ssshhhh...how are they doing it?" – Jeff Yates Mar 18 '10 at 13:10
  • 2
    This won't answer your question, so just a comment about the assumption "at some point it [the credit card info] needs to be stored": Theoretically, that wouldn't even be necessary - if only SET had gained more traction: http://en.wikipedia.org/wiki/Secure_Electronic_Transaction – Chris Lercher Mar 19 '10 at 19:19
  • 2
    I had a contract working on a system for a major hotel chain. Their solution was to use a flat-file database that stored not only the card number, but the raw data track from any swiped cards. In plaintext. On the box under every front-desk. With the same (widely-known) root password used nationwide. This was about 3 years before the PCI standards were put in place. I hope things have gotten better over there. – Brad The App Guy Mar 26 '10 at 16:52

11 Answers11

31

If I was storing the number, I would be a giant service provider with a massive database. That database is spread across a highly-redundant storage array consisting of multiple cabinets, in separate rooms or ideally in separate geographical locations, connected by a SAN. My biggest insider threat is the distributed physical plant, the constant stream of worn-out drives, and several daily shifts of technicians, administrators, and engineers. It's a huge threat.

Therefore I would encrypt the data on a physically-isolated computer that connects to the mass storage over a network. The software would be as simple as possible: encryption and number verification. The public interfaces and business logic goes elsewhere. Accesses would be logged to a separate SAN.

Encrypt with something like AES. The raw AES key is only ever stored in RAM. The key is wrapped in a PGP file for each administrator, who has their own passphrase to enable the server. Less-trusted personnel can be given partial passphrases to use in disaster recovery, or passphrases can be stored in a vault somewhere. For encryption, pick a unique initialization vector (IV) for each card number, AES-encrypt the number using that IV, and store the IV and encrypted number to the SAN. Decryption only occurs using a privileged client interface; normal client connections used for purchases can never get a decryption.

Daniel Newby
  • 2,392
  • 18
  • 15
  • 1
    +1 for discussing a lot of the security concerns beyond just encryption. I've developed software for payment service providers, and key management is certainly the most challenging area of card security, which I discussed here: http://stackoverflow.com/questions/1583553/how-to-properly-do-private-key-management/1584586#1584586 – PaulG Mar 17 '10 at 17:13
  • AES is symmetric encryption. Therefore in order to encrypt, the client's session will need to have access to the symmetric key which means that essentially it will always have to be made available in the server's memory in order for any transactions to work or else they will not be able to encrypt the data. However wouldn't it be better to use asymmetric encryption so that encrypting the sensitive data wouldn't even require access at all to the decryption key? This would therefore allow you to shut down the memcache (or equivalent) server until needed and allow transactions to still go through – Mike Jul 15 '11 at 00:51
  • @mike Surely if you have an online transaction system you can't just shut down part of your memory until needed - system would be transacting all the time, both encrypting and decrypting data. I guess there may be some advantage in separating the encryption & decryption applications, however. – saille Apr 23 '15 at 04:40
  • @saille "I guess there may be some advantage in separating the encryption & decryption applications" That's exactly what I was thinking. This would allow you to have two access levels, one to encrypt or update and one to decrypt. Since the public key is, well, public, the access levels to encrypt something could be much more lenient than the decryption access level. I actually did implement my own data encryption system recently and I actually went with both asymmetric and symmetric encryption. A symmetric key is used as a key encrypting key to encrypt the private key which encrypts the data. – Mike Apr 23 '15 at 19:34
19

For vendors to process and store your credit card info, they generally have to get PCI certified. The requirements should be outlined here. Some of the requirements are very straightforward, and others are vague and open to interpretation. Going through the process is not fun, and a company having the certification doesn't mean your data is safe.

But it's better than nothing I suppose.

i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
  • 6
    Agreed. Many of the companies who have been hacked and had credit card information stolen were PCI compliant. It's not the end-all and be-all. – John Conde Mar 17 '10 at 00:26
  • 2
    Absolutely correct John - in fact, many companies take a complacent attitude towards security simply because they've met PCI requirements, causing their management to believe they're secure. – wadesworld Mar 17 '10 at 20:59
  • 1
    PCI compliant is pretty useless. They take the word of the person answering the survey to determine PCI compliance. There are questions of the nature: is your blah blah secure? What do you think someone trying to get PCI compliance will answer? – OverClocked Mar 18 '10 at 03:33
  • 3
    @Overclocked. Only very small mail-order style clients can get away with using the self assessment questionnaire. Most (all ecommerce merchants) will need to bring in an independent Qualified Security Assessor. If you lie and get caught, you get fined and blacklisted – PaulG Mar 18 '10 at 07:24
  • 2
    @Overclocked: also, they must get a vulnerability scan from an Authorized Security Vendor, which means they can't just answer the survey to assume compliance. – Jason M Mar 22 '10 at 17:10
3

It's quite easy to store a salted hash of a credit card number rather than the number itself for secure lookups. For 99% of the scenarios out there, this would be sufficient credit card for storage -- fast and very secure.

If you really need reversible encryption of a credit card for some scenario (continued billing, for example), I would go with a symmetric key stored in a secure location other than the database. It's been a while since I looked at PCI specs, but I'm fairly certain that's PCI compliant.

If you need fast lookups along with reversible encryption, use both options: a hash and an encryption.

Edit: There seems to be some controversy over my answer. I would like to point out the following very interesting essay from Integrity.com (PDF):

Hashing Credit Card Numbers: Unsafe Application Practices

It details many of the issues involved in storing a hash of credit card data, but its conclusion confirms my suggestion.

Yes, a raw hash of the card is not secure; that's why we salt our hashes! But a static salt is also not secure, they allow the creation of rainbow tables for known static salts. So it's best to make our salts vary in some way that is unpredictable. In the case of passwords, it's sufficient to use a separate, random hash for each password being checked; it can even reside in the same table/row as the hashed password. For the case of credit cards, this should be the same -- a random salt for each instance of the credit card being hashed. If the credit card number is stored per transaction, a separate salt for each transaction.

There are pros and cons to this approach, but it's sufficiently secure. The pros are the lack of key management; the salt and hash are right there, and don't need to change while still allowing for audit checks of the hash; e.g. does that credit card hash match this known credit card number?

The cons are in search; it's not possible to effectively search for a particular credit card number across many transactions.

Of course, you'll have this issue with external encryption anyway; unless the database is itself encrypted (something only some databases support), you won't be able to search very well. Even then, encrypting at the database or even the table level reduces search effectiveness significantly.

Randolpho
  • 55,384
  • 17
  • 145
  • 179
  • 1
    This is bad advice. Credit cards numbers are not very random. Unless you carefully design your implementation, this will not be secure as the hashes can be brute-forced. – Turtle Mar 17 '10 at 01:19
  • But the salt is public, so having the salt and the hash it's relatively easy to test all the possible credit card numbers for a match. – Kris Mar 25 '10 at 17:46
  • Only if the salt is both public and static. Salts should always be transaction specific. I will modify my answer to explain this. – Randolpho Mar 25 '10 at 18:29
  • 3
    I still think @Turtle is right. The problem is not rainbow tables that you can use to unhash other cards, the problem is that there is NO margin for error with credit cards. With passwords, users can (hopefully) choose any length using numbers, letters and symbols. It is not very easy to brute force that, but with credit cards, often the first and last 4 digits are stored in plain text, which leaves only 8 unknown numbers. Even if those numbers were completely random, there are only 100 million numbers you need to try to be guaranteed to get the full number, no questions asked. – Mike Mar 06 '13 at 00:38
  • I wanted to provide an update to my last comment. The PCI DSS v3 in section 3.4 does permit hashing cards, but great precautions must be taken. It must be based on strong crypto (so md5/sha1 are out and hopefully you choose something slow), you must use a random salt to prevent rainbow table lookups, the hash must be of the entire card, and the hash and the truncated card (i.e. first and last digits) must never come into contact. *If* you are going to hash your clients' cards, study PCI DSS section 3.4 to make sure you do it right and make sure you read the rest of the document too! – Mike Apr 23 '15 at 19:50
2

The last few times I worked with creditcard payments, you never really stored the actual CC info on your own servers. You let the Payment gateway handle that. What you ended up with was a transactionID that you could use to verify that the creditcard was still both valid and had the requested amount of cash available. Then once you actually packed the stuff they bought, you'd issue a capture-command to the Payment Gateway.

This approach greatly simplified the process of integrating CC payments on a site, since all you ever needed to know was the transactionID for a particular customer. This ofcourse didn't allow you do to the amazon-"trick" of keeping your CC info for 1-click shopping. If the transactionID got compromised, all it could be used for was collecting payment early, or cancelling the transaction altogether (in which case you'd find out about it when you verified that the authorization was still valid before shipping). The transaction couldn't be used to collect a bigger sum than what the customer had approved already, nor would it allow someone to collect to a different account than what the "shop" was configured for.

Maybe not the exact answer you were looking for, but perhaps it could solve your overall issue without having to spend a fortune on security vendors.

Grubsnik
  • 918
  • 9
  • 25
2

Your assumption that the merchant must store the card somehow is incorrect. Most likely, the merchant is storing a token that it received from the payment processing gateway the first time you used the card. The token uniquely identifies the combination of merchant and card. Subsequently, you can make purchases from that merchant without supplying your card number again. If the merchant's database is compromised, the tokens are of little value to the attacker. They're only valid for that merchant, and they can all be canceled at once when the breach is detected.

Kevin Krumwiede
  • 9,868
  • 4
  • 34
  • 82
1

In some situations, encryption keys are stored not on disk but on some hardware device. Either a special encryption server is used to do the encrypt/decrypt or the decrypt is done using a key stored on, say, a hardware dongle. This way, a hacker cannot steal the decrypt keys without stealing the physical device containing them (since the key never leaves the device).

Another method I have seen is to store encrypted data in a database/datacenter that has no direct connection to the outside world (you can't hack what you can't access). An interface server sits between the "secure" part of the network and the "Internet-facing"/"insecure" part of the network as a proxy. Forcing secure traffic to funnel through this security choke point can make it more difficult for an intruder to access the secured data.

Neither of these mean your data is perfectly secure, of course.

bta
  • 43,959
  • 6
  • 69
  • 99
1

As an merchant you can choose to store the CC data in your own database or outsource it to third party providers.
Third party providers like IPPayments or major banks like Westpac in Australia are level 1 PCI compliant. For web applications you can choose to use a payment acceptance web page (presented somewhere in your customer's workflow) from them branded for your company. For windows apps (e.g. you company's CRM app) and recurrent payments they generally have a gateway usable using their API that provide a tokenisation service, that is they accept a CC number, registers it and return an unique token that just looks like a CC number. The token can be safely be stored in your DB and used for any further transactions, batch payments, reconciliation etc with the bank. Of course they big issue is operational cost per transaction. For a utility that takes monthly credit card payment from a million customer the transaction cost can be substantial.

If you choose to store the CC number in your own DB triple DES encryption is sufficient. A better option is to you transparent encryption in DB as offered by Oracle advanced security or SQLServer where even the DBA cannot decrypt the CC number. Then there are onerous responsibility for key management, backup, physical security, network security, SSL transmission, changing default settings of all server equipments and firewall, anti virus, auditing, security cameras and on and on ...

softveda
  • 10,858
  • 6
  • 42
  • 50
1

First of all if you deal with credit card numbers, you will need to become PCI-DSS compliant, and once you store numbers all 12 sections of the PCI-DSS spec will apply to you. Thats a major cost to most organisations, and if you don't have the time, resources and financial means, you should not go down the path of storing credit card numbers.

We have gained PCI-DSS compliance on a Windows based e-commerce system that stores credit cards. It uses a 256 bit AES encryption. The key itself is encrypted using Windows DPAPI meaning it can only be decrypted by a process running under the same user account as the one that encrypted it. The encrypted key is stored in the registry.

The key is rotated every 12 months, and a backup key copy is stored broken into 3 parts A,B,C and spread over 3 USB drives, each held by a different person. Drive 1 has A+B, Drive 2 has B+C, Drive 3 has A+C. So any 2 drives are required to construct a full key (A+B+C). This scheme is tolerant to the loss of any 1 of the drives. Key parts themselves are encrypted with a password known only to the drive owner.

saille
  • 9,014
  • 5
  • 45
  • 57
  • Thats incorrect, or maybe times have changed. I know several PCI SAQ-D compliant (highest and most stringent level of PCI compliance) that handle the server and security for you, then you just need to store the card data securely with encryption and all. OVerall, say max $800/m – eozzy Dec 07 '12 at 04:27
0

To answer your specific question, it is possible to store the credit card encryption key encrypted on disk. The key encrypting key can derived from a passphrase that must be entered when the server is started. Shamir's secret splitting scheme can be used so that k out of N shares are required to construct the secret that will be used as key encrypting key. The decrypted encryption key/secret is then stored in memory. If the server has to be restarted, then you need k shares. This is of course a big overhead and most merchants I know do not implement this. They do however usually store the key separately from the encrypted data for some intermediate security, so access to one does not automatically mean access to the other in entirety (still very bad though).

I deleted contents of my original post since that did not directly answer the question. Suffice it to say that key management and correct encryption are an important piece but still a small part of the story.

PCI auditors cannot possibly ensure that everything is done correctly.

mar
  • 356
  • 1
  • 6
0

If you want to eliminate any credit card stealing headaches, hash them using salt values not stored in the database (in addition to salt values stored in the database). Hashing them with any modern hashing algorithm will pretty much put to rest most issues with credit card theft but it does mean consumers must re-enter their credit card on each purchase. Having worked on a project that dealt with storage of credit card numbers, I found that hashing them cut security review costs by an order of magnitude (granted that project was before PII concerns).

If you are going to use symmetrical encryption, then you enter a new realm of complication that all comes down to management and control over the decryption keys. I will say that even if you hash the credit card numbers you will still need to deal with reversible encryption since all PII(Personally Identifiable Information) must be encrypted. SQL Server 2008 has a new Extensible Key Mangement plugin architecture which lets use third-party vendor programs to manage control over the decryption keys including split keys.

For more info: Deploying SQL Server 2008 Based on Payment Card Industry Data Security Standards (PCI DSS) Version 1.2.

Thomas
  • 63,911
  • 12
  • 95
  • 141
  • I guess that "hashing with secret salt" amounts to using some sort of MAC. – Kris Mar 25 '10 at 17:49
  • If you do this, be certain not to *also* store some fragment of the credit card number. You may be tempted to store the last four digits of the number so you can show it to the user. However, given the very predictable format of the first few digits, if the attacker has the hash and the last four -- it is actually possible to just brute force it.... I've done it! – MtnViewMark Mar 26 '10 at 02:21
  • 1
    You certainly did not do it without all the salt values. The simple solution is to have two salt values: one per entry and one outside the database. You'd have to have both values in order to do a reasonable brute force. – Thomas Mar 26 '10 at 03:18
-3

any automated system for decrypting encrypted information is going to be completly insecure. By automating the process you are defeating the encryption. Any encrypted data should only be decrypted by a user entered secret key.

Medran
  • 433
  • 3
  • 10
  • Credit card servicers need to separate the security maintenance and mass storage maintenance duties. Ergo encryption. – Daniel Newby Mar 17 '10 at 00:39