3

I am using Java Smart Card API to access. I have NXP Mifare desfire 4K , 1K , Ultra light smart cards with me & trying to find out its type programically in JAVA.

I referred to document AN10833 from NXP site (http://www.nxp.com/documents/application_note/AN10833.pdf). I have following queries related:

  1. How to get SAK using JAVA?
  2. what is APDU to execute REQA command?
  • Show us something you've tried, and we might be able to help you. – mthmulders Apr 12 '13 at 09:12
  • By using Native commands, I have already retrieved below information,1)cmd : 90, 60,00,00,00 response> 04 01 01 00 02 18 05 2)cmd : 90,AF,00,00,00 response > 04 01 01 00 06 18 05 3)cmd : 90,AF,00,00,00 response 04 2C 32 F9 B8 23 80 8F D5 15 49 20 10 09. Here UID- 04 2C 32 F9 B8 23 80 batch number - 8F D5 15 49 20 week 10 year 09 UID[0] is 04 NXP Semiconductors. But I am not able to identify type of card whether it ultralight or any other by info return by above commands . – Tanmay Solanki Apr 12 '13 at 12:12
  • Did you try to follow the steps at the end of the [package summary of `javax.smartcardio`](http://docs.oracle.com/javase/6/docs/jre/api/security/smartcardio/spec/javax/smartcardio/package-summary.html)? – mthmulders Apr 12 '13 at 12:16
  • There is one method of using Get DATA APDU to get ATQA SAK UID as: 0xFF,0xCA,0xF0,0x00,0x05, But the response is coming as blank ? – Tanmay Solanki Apr 12 '13 at 12:20
  • The steps at the end of the package summary of javax.smartcardio are to execute APDU command. I am using same method to execute my APDU commands. – Tanmay Solanki Apr 12 '13 at 12:22
  • @TanmaySolanki don't forget to accept (and upvote) an answer if it answers your question. In your case I would strongly recommend vikky's answer (if only because it currently is the only answer, and seems to fully address the issue). – Maarten Bodewes Apr 25 '13 at 21:20
  • See the next link. I am use smartcardio [http://stackoverflow.com/questions/21511312/smartcardio-terminal-connection-error-in-pcsc-gemplus-javacard](http://stackoverflow.com/questions/21511312/smartcardio-terminal-connection-error-in-pcsc-gemplus-javacard) – Ronald Coarite Nov 25 '15 at 22:40

3 Answers3

5

Find out the ATR of the card and ATR contain the the information of card type. Here I am uploading image See the structure of ATR... For more info Here the full PDF look at Page no 6.

enter image description here

enter image description here

jiten
  • 5,128
  • 4
  • 44
  • 73
  • 1
    Very nice anwer, vikky. The only comment I would have is that for contactless cards my company usually refers to this information as the ATS (answer to select instead of answer to reset) for contactless cards. +1 hopefully more upvotes will follow... – Maarten Bodewes Apr 16 '13 at 23:27
1

edit: Apologies that this does not directly answer the question but the current top answer is potentially harmful. I'm trying to discover how to get the SAK myself will try to post an update when I do.

Determining card type from the ATS/ATR is commonplace, but wrong. NXP advises using SAK.

"As the ATS of different MIFARE ICs can be customized, it is certainly not advisable to rely on the ATS to differentiate the IC type"

Ref: http://www.nxp.com/documents/application_note/AN10833.pdf

Instead, look here for a detailed tree of how to determine card type from the SAK: http://www.nxp.com/documents/application_note/130830.pdf

As an aside, in production if you can be assured that you will always get the same format of ATR/ATS on all your cards, that can be a viable option. But it is not guaranteed.

I have no idea what in the world VCA is, but from the first document:

"In future, NXP recommends to use “Virtual Card Architecture (VCA)” for PICC selection and type identification. If installations do not depend on the actual content of ATQA, SAK and/or ATS for card selection and identification, this allows for more than one MIFARE product being enabled for activation in a single device at the same time. In this case, the VCA allows for efficient and privacy friendly selection of the targeted MIFARE product. This is described in a separate application note."

  • Late followup: We were never able to find a satisfactory solution. Due to the ATS/ATR being customizable, the best method we could find was just to have context-dependent checking. Example: A debug program would allow you to select what type of card to try, and returned as to whether a connection could be obtained. This means we can't say the wrong type was tried, we can only say connection could not be obtained. – Kevin Dildonik Jul 26 '16 at 19:02
1

I know this is an old blog but I have been working on this same issue and wanted to share my findings.

In AN10833 it clearly states that the UID + SAK are returned from performing a select. Using the java smartcard io library I can perform a select like this:

// Send pseudo APDU to retrieve the card serial number (UID)
int cla = 0xFF;
int ins = 0xCA;
int p1 = 0x00;
int p2 = 0x00;
byte[] data = null;
int dataOffset = 0x00;
int dataLength = 0x00;
int le = 0x00;

CommandAPDU getDataApdu = new CommandAPDU(cla, ins, p1, p2, data, dataOffset, dataLength, le);
ResponseAPDU r1 = channel.transmit(getDataApdu);

However, I am only returned the UID. I found documentation on the PC/SC API that changing P1 = 0x01 will change the response to the historical bytes (which worked for me).

(section 3.2.2.1.3 from here: http://pcscworkgroup.com/Download/Specifications/pcsc3_v2.01.09.pdf)

Unfortunately, for the off-the-shelf readers I have access to I could not find the parameters to return the SAK. In a different reader's API document I found that if p2 = 0x01 the ATQA + UID + SAK is returned (this reader is propitiatory and I cannot share the doc).

I believe if your reader supports it (or you are coding at a low enough level to control the reader itself) you can get/request the exact SAK. Otherwise you may need to use the ATS/ATR to determine the card type.

Note, in Java here is the code to grab the ATS/ATR:

// wait 10 seconds for a card
CardTerminal terminal = terminal.waitForCardPresent(10000);

Card card = terminal.connect("*");
ATR atr = card.getATR();

From there, the ATR can be processed as vikky mentioned above.

I will respond with anything else I learn.

riiich
  • 861
  • 8
  • 12