In section 3.3 of the PCI standard, it says that when displaying PANs, limiting visibility to the first 6 and last 4 digits of the PAN is considered secure. Doing some quick math, on a 16 digit PAN, taking into account the checksum requirement, this leaves only 100,000 card numbers to brute force in order to get the one I want.

If a hash were supplied as well, this would be stupidly easy to crack, but what's stopping me from spamming some e-commerce site with a script until it tells me I'm right? That shouldn't take very long either. I know having to guess the 3-digit security code is going to bring me up to 100M guesses, but not everyone uses this code.

My company's database supplies me with name, address, card type, truncated PAN, and expiry date of the card/holder, and this seems like plenty of info for an attack (at least social engineering). If I'm reading the PCI standard correctly, this also complies with it.

What am I missing?

I'm using this handy table (page 2) for quick reference

3 Answers 3


I think it makes more sense in the context of how much extra information is being given away, rather than how easy it'd be to brute force the remaining digits.

A PAN is not entirely a random value, it's made up of:

  • a six-digit Issuer Identification Number (IIN) (previously called the "Bank Identification Number" (BIN)) the first digit of which is the Major Industry Identifier (MII),
  • a variable length (up to 12 digits) individual account identifier
  • a single check digit calculated using the Luhn algorithm


Therefore using this information:

My company's database supplies me with name, address, card type, truncated PAN, and expiry date of the card/holder

You could probably narrow down the first 6 digits pretty easily to quite a small set of possibilities.

That only leaves the last 4 digits, one of which is a check-digit and therefore doesn't contain any additional entropy.

So basically you're only giving away 3 digits, even if all 10 that are allowed are exposed.

this leaves only 100,000 card numbers to brute force in order to get the one I want

I'm guessing it would be fairly hard to execute such a brute force attack as most payment processors would lock you out very quickly.

PCI DSS also says:

Note: It is a relatively trivial effort for a malicious individual to reconstruct original PAN data if they have access to both the truncated and hashed version of a PAN. Where hashed and truncated versions of the same PAN are present in an entity‘s environment, additional controls should be in place to ensure that the hashed and truncated versions cannot be correlated to reconstruct the original PAN.

Which should prevent the attacker from staging an offline brute force attack.

Also, these are the minimum requirements. It states in principle 7 that:

Requirement 7: Restrict access to cardholder data by business need to know

I imagine displaying all 10 allowable digits to customers would fall outside "need to know". Perhaps the last 4 are required to identify which card is which, but most users wouldn't need to know the first 6 except perhaps to be shown what type of card it is.


Best guess, short version:

  1. It's rooted in physical practices and has been retained into digital practice
  2. It's not significantly different from brute force guessing without it


Historically, truncated numbers are printed on receipts because they provide enough information to allow identification for chargebacks in a return or refund. For physical card merchants, they may not have as sophisticated a database as eCommerce merchants do. Without that info on the receipt, it is harder to match up the transaction.

Bear in mind that the first 6 is the IIN (aka BIN) number, all of which are well known. If someone wants to brute force a card, they can select a BIN and they'll know the card brand from that. Brute-forcing the remaining 10 (without truncated data to provide the last 4) is harder than the remaining 6 (if you have the truncated number) but it's not a world of difference.

Put differently... in mathematical terms, brute-forcing a full card is relatively trivial, at 10^10 complexity (10 digits, 10 places, plus 6 BIN already known). Dropping it to 10^6 is significant but not earth-shattering; both are far easier than a 8-digit alphanumeric password at 26^8. But:

Finally, brute-forcing isn't offline. You can't brute-force in a vacuum, you have to pump your transaction attempts through a merchant, a processor, and the card brand. All of whom have some degree of checking for brute force attacks. It's fair to say the card brands are sophisticated in their analysis and ability to react to a brute force attacks. Merchants will be less so, but more simply motivated in that they get charged for failed authorization attempts, so a brute force attack runs up their bill.

Would it be better to require encryption or hashing? Sure. But, see #1. Legacy practices can linger if they're not completely broken.


There's a lot of guesswork in this answer, based on tidbits of knowledge and reasonable logic. I'm very interested in seeing someone come up with a better answer based on fuller knowledge.


The other posts made the succinct point of saying the processors should shut you out quickly if you spam them with auth attempts, so it's doubtful you would make much headway there.

If a hash were supplied as well, this would be stupidly easy to crack

If by hash you mean the output of a hashed PAN, then it depends on the algorithm employed. Consider an algorithm that uses a time based work factor (bcrypt, scrypt, pbkdf2) with a compute time of about 0.5 sec. Of the 100k possible outputs, let's say it takes 50k attempts to match one. That comes to about 17 hours to make a match. And if proper salting was used, you only get the key for one card and have to start over for the next.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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