How to be PCI compliant yet weak
It’s possible to comply with the PCI DSS yet provide essentially no protection to credit card numbers. Here’s why.
Section 3.3 of the PCI DSS requires this:
Mask PAN when displayed (the first six and last four digits are the maximum number of digits to be displayed).
Then section 3.4 requires this:
Render PAN, at minimum, unreadable anywhere it is stored (including on portable digital media, backup media, in logs) by using any of the following approaches:
- One-way hashes based on strong cryptography
- Index tokens and pads (pads must be securely stored)
- Strong cryptography with associated key-management processes and procedures
Each of these techniques seems to provide a reasonable level of protection for credit card numbers, but when you combine the two, it turns out that the combination can actually be fairly weak. Here’s why.
If you mask a credit card number, you can keep the middle six digits and hide the rest. So you might turn this credit card number
1234 5678 9012 3456
1234 56XX XXXX 3456
Now suppose that you also know that the SHA-1 hash of this credit card number is the value
This is enough information to let a hacker quickly and easily find the complete credit card number: all he has to do is calculate the SHA-1 hashes of all possible credit card numbers that begin with 123456 and end with 3456. There are only one million of these, and it’s possible to calculate that many hashes extremely quickly. Even on extremely my old laptop, I can do that in less than a couple of seconds. Hackers who have even more modern computers can do it even more quickly.
So if you have both the hash of a credit card number and a masked version of the same credit card number, then it can be extremely easy to find the entire credit card number. Each of the ways to protect credit card numbers may be good enough by themselves, but together they can provide essentially no security.
I've heard of more than one case where masked data from one application and hashed data from a different application gets stored in a common database, so this particular vulnerability is not purely of academic interest.