« Last post by MrBogosity on February 21, 2017, 05:16:54 PM »
No, the PIN can be a part of hardened crypto if you do it right.
Just spitballing, but something like this:
acct = <account number>
PIN = <PIN>
key = <random 256-bit number local to the card, that never leaves it>
PrivKey = Ed25519(HMAC(key <key>, acct||pin <message>))
PubKey = PrivKey.MakePublicKey()
The bank or payment processor would have the public key, which is all it would need (and it would be regenerated whenever the PIN is changed). So, when the card is used, you use the same technique to make the same PrivKey in the card, and then:
Sig = PrivKey.MakeSignature(TransactionID <message>)
The signature would then be sent to the bank, which would verify (or reject) it with the public key.
All keys would have the full 256 bits of entropy thanks to the random number on the card, which is absolutely necessary for the crypto. The PIN isn't stored anywhere; the user types in the correct PIN, which results in the crypto working, or an incorrect PIN, in which case the crypto fails.
You wouldn't even need to encrypt the data (or at least, this part of it) since nothing is transmitted which needs to remain secret, or can be substituted by a MITM in any way that will result in anything except a failed transaction.