How can I determine a Smart Card ATR mask?
Given a Smart Card ATR (Answer-To-Reset);开发者_如何学编程 Is is possible to determine which bytes that can be variable to create an ATR Mask for the particular card?
An example ATR might look like (which can be parsed by Ludovic Rousseau's ATR parser):
3B FF 18 00 FF 81 31 FE 45 65 63 11 05 40 02 50 00 10 55 10 03 03 05 00 43
Is there any generic way to accomplish this? Or do I have to contact the card vendor for the particular card?
It depends on the goal. If your goal is to be able to identify that exact card type in all possible variations, there is no way an ATR mask will do that for you. If you have a general card "family" you want to associate, you might try masking out the historical bytes. If you are setting Calais registry settings, I suggest NOT masking out anything because you might block another CSP. Other than ATR, look at the latest Microsoft Mini Driver spec for a process to identify a card.
What is the application of this knowledge?
I don't believe there is a standard for this, other than variable bytes in different card characteristics (if it is known that there are different versions of a given card, with different protocol capabilities for example), or if you know that there are different releases of the card. Sometimes you can find information about a card from the historical bytes, such as there are different vendors for Estonian eID card, but the historical bytes of all cards read "EstEID v1.0" in ASCII.
So the answer most probably is you need to contact the manufacturer or read the documentation that came with the card.
Good luck!
I find the type of mask by TA bit in ATR. TA is 0 bit in Interface bytes of ATR. Then I find the manufacturer of the mask by 8 bytes from the bottom/end address of card. I execute the below APDU cmommand after ATR :
CommandApdu commandApdu = new CommandApdu(0xBC, 0xC0, 0x00, 0x00, data, 0x08);
Then I verify the 2nd and 3rd bits (bits = 0, 1, admax[0]=2, admax[1]=3, 4, 5, 6, 7) :
byte[] result8Bytes = responseApdu.getData()[2];
byte[] adMax = new byte[2];
adMax[0]=result8Bytes[2];
adMax[1]=result8Bytes[3];
if (ATR_TA == 0x0E) { //SCOT
if (adMax[0] == 0x21 && adMax[1] == 0xA0) `
typeMasque = SCOT_400_M9V1;`
else if (adMax[0] == 0x21 && (adMax[1] == 0x19 || adMax[1] == 0x88))
typeMasque = SCOT_400_MOT;
else if (adMax[0] == 0x88 && adMax[1] == 0x00)
typeMasque = SCOT_400_STM;
else if (adMax[0] == 0x19 && adMax[1] == 0x00)
typeMasque = SCOT_300;
else
typeMasque = SCOT_INCONNU;
}
if (ATR_TA == 0x0D) //IGEA
if (adMax[0] == 0x20 && adMax[1] == 0xA0)
typeMasque = IGEA_340_AMTEL;
else if (adMax[0] == 0x21 && (adMax[1] == 0x20 || adMax[1] == 0x98))
typeMasque = IGEA_440_BIS;
else if (adMax[0] == 0x21 && adMax[1] == 0x20)
typeMasque = IGEA_440_STM;
else
typeMasque = IGEA_INCONNU;
}
精彩评论