Why your PIN block decodes to the wrong PIN
The XOR carries no integrity check, so the wrong PAN produces a valid-looking length and four numeric digits. Here is why, and the one field that tells you it happened.
You have a clear PIN block, a PAN, and a PIN that comes back wrong. The obvious conclusion is that the block is corrupt — and it usually is not. An ISO 9564 format 0 block decoded against the wrong PAN does not fail, does not warn, and does not produce anything that looks unusual. It produces a different PIN.
Here is a real one, built and decoded by PIN block toolkit as this page was generated.
The same block, two PANs
PIN 1234 on PAN 4111111111111111 gives this block:
PIN field 041234FFFFFFFFFF
PAN field 0000111111111111
────────────────
block 041225EEEEEEEEEEDecode it with the PAN it was built from and you get 1234, as you must. Decode the identical block with 5555555555554444 instead and you get 1270 — four digits, no error, nothing to suggest anything went wrong.
Why nothing catches it
A format 0 block is the PIN field XOR-ed with a field built from the PAN. XOR is reversible with any value, not only the right one — that is the entire mechanism. Feed a different PAN and every nibble changes by a different amount, but the result is still sixteen nibbles, and the parts a decoder checks are still shaped correctly.
block 041225EEEEEEEEEE
PAN field 0000555555555444 ← from 5555555555554444
────────────────
result 041270BBBBBBBAAA
││└─ digits: 1270
│└── length: 4
└─── format: 0The padding is the only tell
Format 0 pads with F. A correctly decoded block therefore ends in a run of F nibbles, and that is the single piece of evidence available.
right PAN FFFFFFFFFF
wrong PAN BBBBBBBAAA ← not F, so the PAN is wrongIf your decoder does not check that, it will hand you a plausible wrong PIN and let you spend an afternoon on it. That is why the tool on this site reports the decode as successful — the block genuinely does say that — while warning, in the same breath, that the padding says not to trust it.
The other way to get this wrong: which twelve digits
The PAN field is the rightmost twelve digits excluding the check digit, and the order of those two operations is where implementations go wrong. Drop the last digit first, then take twelve from what remains.
correct drop check digit → 453201511283036
rightmost twelve → 201511283036
wrong rightmost twelve of the whole PAN → 015112830366What to do when the HSM says verification failed
The response is the same whether the PIN was wrong, the PAN was wrong, the format was wrong or the key was wrong. It cannot tell you, and it is not being unhelpful — it does not know either.
So work backwards from the clear block. Build the block you expect from the PIN and PAN you believe are in play, and compare it with the one you are sending. If they differ, the fault is in the formatting rather than the credential, and the two fields shown separately will say which half moved.
PIN block toolkit builds and decodes formats 0 to 3 in your browser, showing the PIN field, the PAN field and the XOR as separate lines. Nothing you type into it is transmitted anywhere — but use test PINs and test PANs regardless.
Check it against the tool
- ISO 9564 PIN block calculator and key component combiner
Build and decode clear PIN blocks in formats 0 to 3, combine key components, and compute key check values.
- Luhn validator and test card number toolkit
Check a Luhn digit and see the arithmetic, identify the card network from its IIN, and look up published sandbox cards.
Frequently asked questions
- Which twelve digits of the PAN go into a format 0 PIN block?
- The rightmost twelve excluding the check digit, and the order of those two operations is what people get wrong. Drop the last digit first, then take twelve from what remains. Taking the rightmost twelve of the whole PAN shifts every digit by one position and produces a block that is wrong in a way nothing downstream can describe. A PAN shorter than thirteen digits is left-padded with zeros.
- Why does decoding with the wrong PAN give a PIN instead of an error?
- Because a format 0 block is just the PIN field XOR-ed with the PAN field, and XOR has no integrity check in it. Undo it with a different PAN and you still get sixteen nibbles: the first is still the format code, the second still reads as a length between four and twelve often enough to pass, and the digits after it are still digits. Nothing in the arithmetic knows the PAN was wrong.
- How can I tell the PAN was wrong?
- The padding. Format 0 pads with F, so a correctly decoded block ends in a run of F nibbles. If the padding is anything else, the PAN you decoded with is not the one the block was built with — and the PIN above it, however ordinary it looks, is not the cardholder's. This is the only signal available, which is why a decoder that does not check it is actively dangerous.
- Does this affect format 1, 2 or 3?
- Formats 1 and 2 carry no PAN at all, so there is nothing to get wrong — but that is a weakness rather than a feature: without the PAN binding, the same PIN produces the same block on every account. Format 3 folds the PAN in exactly like format 0 and has the same failure, with one difference: its padding is random within A to F, so a digit appearing in the padding is a signal, but F padding is not the expected shape and cannot be used as a check the same way.
- The HSM says PIN verification failed. Is the block wrong or the PIN?
- The HSM cannot tell you, and that is the whole problem — a wrong PIN, a wrong PAN, a wrong format and a wrong key all produce the same response. Working backwards from the clear block is the only way to separate them: build the block you expect from the PIN and PAN you think are in play, and compare it with the one you are sending. If they differ, the fault is in the formatting rather than the credential.