-4

Why is the following database table not secure? Which encryption method is better for credit cards?

+--------------+-------------------------------+-----------+--------------+
| customer_id  | card_number                   | card_cvv  | card_expiry  |
+--------------+-------------------------------+-----------+--------------+
| 2315         | ODU2OS0xMjU0LTc4NTQtMzI2NQ==  | MjU4OQ==  | May 2018     |
+--------------+-------------------------------+-----------+--------------+
5
  • 25
    This has been eluded to in the answers, but is worth stating explicitly: Base64 is NOT encryption. Encryption means that you need some sort of secret key in order to read the data. Base64 does not require a key. For example, your second field decodes to 8569-1254-7854-3265. – Dan Landberg Aug 11 '17 at 13:37
  • 17
    For anyone concerned, that number is a test number. It does not pass luhn validation, so it isn't a real CC number. – AJ Henderson Aug 11 '17 at 14:44
  • 3
    I'm curious about the background of this question. Is this a homework problem? If not, are you designing a DB to store credit card? – Andrew T. Aug 11 '17 at 17:26
  • 7
    Please make sure you've thoroughly reviewed the PCI guidelines for storing credit card information, and that you conform to them; this is the canonical resource for storing CC data in most of the world. Ideally, offload your payment information storage to a PCI-certified third party if possible. Most importantly, understand the difference between encryption and encoding before even attempting to implement payment information storage and handling. – Jules Aug 11 '17 at 17:58
  • 4
    If you have to ask this question, you should not be designing a production table to store credit card info. Find someone who knows the concepts and the regulations to handle it. There are numerous vendors who specifically offer compliant systems as a product. If you don't have the internal resources to be handling credit card info properly, there is no shame in outsourcing it. (Quite the opposite. You should feel good about taking the necessary steps to protect the sensitive information of your customers.) – jpmc26 Aug 11 '17 at 20:25
57

It's obviously base64 encoded. If someone steals your database, he can just decode the data and have all credit card from every customer. You could just store as string and have basically the same security, as you are only using more bytes to achieve the same.

To store credit card data, you must be compliant with PCI rules. And PCI explicitly forbids storing the CVV. If your table have a field for CVV, you failed. If you encode it and store, you failed. Even if you encrypt it, you failed. CVV must never be stored in any means.

As for the encryption method, first read PCI documentation. Building a secure credit card storage is a very difficult task and a very serious one, so don't attempt to do it without understanding the correct methods, risks and mitigations, or you will expose your clients to financial losses and yourself to litigation.

1
6

There is more to storing credit card numbers than simply encrypting the data. As ThoriumBR pointed out, PCI requirements dictate not only what information can be stored, as well as how it must be protected, but also set up environmental conditions for the controls that must exist around how the servers handling the data are setup as well as things like the physical controls of accessing them.

Compliance for storing credit card numbers is extremely complicated and costly. Unless you are processing a very high number of transactions, it is much more cost effective to use an existing credit card handling provider who will handle dealing with the credit card information and hand off a secure transaction ID (basically a receipt) after handling the transaction for you. These services cost more per transaction, but are much much cheaper than the costs associated with building a compliant solution and hosting environment to deal with CC numbers and other payment card information.

2

The number is hidden with base64.

Not sure what the intention is, but this is hardly better than just showing the number.

2

8569-1254-7854-3265

How did I know that? I just searched for a Base64 decoder.

According to Wikipedia.

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding.

Base64 is an encoding used for images. You should use encryption (AES-256 or RSA-4096 for example). Anyway, this is credit card information.

This is very serious personal data.

One way hashing functions, truncating and strong cryptography are guidelines. You should not store cardholder data unless it's absolutely necessary. You need to comply with data protection laws as well as credit card standards.

1
  • 1
    "Base64 is an encoding used for images." this is not accurate – schroeder Jul 12 '18 at 12:35
1

In addition to other excellent answers, I'd like to mention Kerckhoffs's principle. Kerckhoffs's principle is summed up in this quote:

A cryptographic system should be secure even if everything about the system, except the key, is public knowledge.

In this case, you assumed that attackers would not be able to determine that you used base64 (which is not an encryption algorithm) to encode the data. The answers above demonstrate that it was trivial to discover that information, and attackers are much, much more clever than this in practice. You should always assume that your attacker can easily figure out what algorithms you used to obfuscate the data. If you had done so, you would have very quickly realized that anyone can simply decode the data, since there isn't even a secret key involved.

Note that switching to an actual encryption algorithm is far from enough for storing credit card information. See other answers detailing the very heavy standards for protecting such data (which go far beyond just the algorithms and into internal company policies and employee behaviors and more).

0

As already noted, the 8569-1254-7854-3265 doesn't seem like valid number (fail to pass Luhn alg and first digits are not like known Bank Code (BIN) - see https://www.bindb.com/bin-database.html), so it might be actually encrypted.

Storing CVV code in plain or encrypted form next to cardnumber definitely makes no sense.

Not the answer you're looking for? Browse other questions tagged or ask your own question.