How do I read the PAN from an EMV SmartCard from Java

I need to read account number from Maestro/Mastercard with smart card reader. I am using Java 1.6 and its javax.smartcardio package. I need to send APDU command which will ask EMV application stored on card's chip for PAN number. Problem is, I cannot find regular byte array to construct APDU command which will return needed data anywhere...

Asked by: Kelvin177 | Posted: 23-01-2022

Answer 1

You shouldn't need to wrap the APDU further. The API layer should take care of that.

It looks like the 0x6D00 response just means that the application did not support the INS.

Just troubleshooting now, but you did start out by selecting the MasterCard application, right?

I.e. something like this:

void selectApplication(CardChannel channel) throws CardException {
  byte[] masterCardRid = new byte[]{0xA0, 0x00, 0x00, 0x00, 0x04};
  CommandAPDU command = new CommandAPDU(0x00, 0xA4, 0x04, 0x00, masterCardRid);
  ResponseAPDU response = channel.transmit(command);
  return response.getData();

Answered by: Elise649 | Posted: 24-02-2022

Answer 2

here is some working example:

CardChannel channel = card.getBasicChannel(); 

 byte[] selectMaestro={(byte)0x00, (byte)0xA4,(byte)0x04,(byte)0x00 ,(byte)0x07 ,(byte)0xA0 ,(byte)0x00 ,(byte)0x00 ,(byte)0x00 ,(byte)0x04 ,(byte)0x30 ,(byte)0x60 ,(byte)0x00};
  byte[] getProcessingOptions={(byte)0x80,(byte)0xA8,(byte)0x00,(byte)0x00,(byte)0x02,(byte)0x83,(byte)0x00,(byte)0x00};
  byte[] readRecord={(byte)0x00,(byte)0xB2,(byte)0x02,(byte)0x0C,(byte)0x00};

  ResponseAPDU r=null;

   try {
     ATR atr = card.getATR(); //reset kartice

      CommandAPDU capdu=new CommandAPDU( selectMaestro   );

       r=card.getBasicChannel().transmit( capdu );

      capdu=new CommandAPDU(getProcessingOptions);
      r=card.getBasicChannel().transmit( capdu );

      capdu=new CommandAPDU(readRecord);
      r=card.getBasicChannel().transmit( capdu );

This works with Maestro card, I can read PAN number, yet now I need to read MasterCard's PAN number. I do not know should I change the read record APDU or select application APDU. Anyone familiar with APDUs?

Answered by: Clark483 | Posted: 24-02-2022

Answer 3

atr = open();

prints("[Step 1] Select 1PAY.SYS.DDF01 to get the PSE directory");
cmd = new ISOSelect(ISOSelect.SELECT_AID, EMV4_1.AID_1PAY_SYS_DDF01);
card_response = execute(cmd);
SFI = NumUtil.hex2String((byte)((1 < < 3) | 4));

// try SFI 1 record 1
prints("[Step 2] Send READ RECORD with 0 to find out where the record is");
read = new EMVReadRecord(SFI, "01", "00");
card_response = execute(read);
byte_size = NumUtil.hex2String(card_response.getStatusWord().getSw2());

prints("[Step 3] Send READ RECORD with 1C to get the PSE data");
read = new EMVReadRecord(SFI, "01", byte_size);
card_response = execute(read);
// the AID is A0000000031010
prints("[Step 4] Now that we know the AID, select the application");

cmd = new ISOSelect(ISOSelect.SELECT_AID, "A0000000031010");
card_response = execute(cmd);
prints("[Step 5] Send GET PROCESSING OPTIONS command");

cmd = new EMVGetProcessingOptions();
card_response = execute(cmd);

// SFI for the first group of AFL is 0C

prints("[Step 6] Send READ RECORD with 0 to find out where the record is");
read = new EMVReadRecord("0C", "01", "00");
card_response = execute(read);
byte_size = NumUtil.hex2String(card_response.getStatusWord().getSw2());

prints("[Step 7] Use READ RECORD with the given number of bytes to retrieve the data");
read = new EMVReadRecord("0C", "01", byte_size);
card_response = execute(read);

data = new TLV(card_response.getData());


Answered by: John441 | Posted: 24-02-2022

Answer 4

You need to do construct a CommandAPDU object and pass it to the transmit()-command.

You should be able to find the precise command in the documentation for your smartcard, but here is one example:

byte[] readFile(CardChannel channel) throws CardException {
  CommandAPDU command = new CommandAPDU(0xB0, 0x60, 0x10, 0x00);
  ResponseAPDU response = channel.transmit(command);
  return response.getData();

Answered by: Ada659 | Posted: 24-02-2022

Answer 5

Did you try looking up in your documentation what 0x6D00 means? It looks like it might mean that the ENVELOPE command is not supported. Have you tried using T=0 protocol instead of T=1?

I would not expect my example to work on your card. I don't know which APDUs the Maestro/MasterCard-supports, so I couldn't give you a working example.

Try giving the command an explicit expected length like this:

byte[] readPan(CardChannel channel) throws CardException {
  CommandAPDU command = new CommandAPDU(0x00, 0xB2, 0x5a, 0x14, 250);
  ResponseAPDU response = channel.transmit(command);
  return response.getData();

Answered by: Adelaide327 | Posted: 24-02-2022

Answer 6

what about using a scanner, getting a picture of the card, scanning the content of the picture with a good java ocr library ( like for example ) and search for a (usually) 16 digit sequence XXXX-XXXX-XXXX-XXXX , then you will get the PAN from any EMV card using java.

Answered by: Arnold194 | Posted: 24-02-2022

Similar questions

smartcard - Accessing smart card with Java

I'm trying to learn about how does Java access smart cards, due to a project analysis. I wonder if there is any kind of virtual smart card which I could use to make some tests with Java? By the way, I've read about Java Card, and looks like it is used to run Java in cards, not to smart card data access using Java, right?

smartcard - Applet ID's and APDU in Java Card

In my project i want to write biometric data (like fingerprint template) on a smart card. After some good study i chose Java card for my project. But i am new to this platform and know very little about this :( I have read tutorials from Sun also, but was unable to resolve some confusions: 1.) I just want to read and write biometric data from the card, so is it necessary to design applet for it on java card...

How to access a smartcard in Java on Linux?

I'm trying to access a smartcard on a linux system on a VM. The USB device is mapped to the VM and can be listed via lsusb (ID 076b:3021 OmniKey AG CardMan 3121). I can access the smartcard via pkcs11-tool and pkcs15-tool. Also firefox can access the token via the /usr/lib/ library. But when I try to access the smartcard from Java, an empty keystore is returned. I'm using the following configuratio...

smartcard - How to interact with a smart card in Java?

Is there is a library (API) in Java with which I can interact with a smart card? Similar to the WinSCard library. I need to be able to connect with the smart card and read data from it. I need to implement it in Java so that I can use it under any OS (Linux, Mac, Windows). Since, the WinSCard library only works under Windows because it uses a DLL (WinSCard.dll). Is there anything as good as WinSCar...

java - smartcard and p12 file creation

I'm trying to create a p12 file (pkcs12). I know that i need a certificate and a private key to create it. I read the certificate from smart card, but i have problems with private key. I know that in smart card there is a private key, but i cannot extract it true? There is another way to use the private key stored in smart card and use it to create the p12 file? I want to use this code: Key...

smartcard - APDU read file java card program

i made java card classic applet using netbeans when i program the read operation i check for the first byte in the APDU to be 0x80 then the second to be 0xB0 then take the offset that i will read from in the file from the byte 2 and 3 then take the number of bytes to be read from byte 4 to be the APDU as the default one 0x80 0xB0 0x00 0x03 0x60 this read 60 bytes from th...

smartcard - What card readers support Java Card?

I Was doing a research on Java Card 3.0 Technology. Basically the requirement is to read smart card details from web browser through Java applet using Java Card. My question is whether Java Card supports all smart card reader or only specific model of devices? Just want to buy the right device which supports Java Card technology I search over Google couldn't find the answer

How to obtain a user's identity from a smartcard on Windows (MSCAPI) with Java?

I'd like to obtain the user's identity from a smartcard (PKI) from a Java fat client on Windows with Sun's MSCAPIProvider. The target is: user opens the app prompted for card prompted for PIN I get the X509Certicate in Java grant access, etc. I have found based on this stackoverflow question sample which...

smartcard - How to get SAK to Identify smart card type using JAVA?

I am using Java Smart Card API to access. I have NXP Mifare desfire 4K , 1K , Ultra light smart cards with me &amp; trying to find out its type programically in JAVA. I referred to document AN10833 from NXP site ( I have following queries related: How to...

smartcard reader - Reading smart card in Java and capturing the data

I am developing a software to POS device using java.Now I am struct on the card reader functionality.I have a card reader which is connected via USB to POS device, and I got card data within notepad when I swipe the card. I want get card data to my application when I swipe the card.But I have no idea to implement this on my application. I would highly appreciate your help with any code samples.

Still can't find your answer? Check out these amazing Java communities for help...

Java Reddit Community | Java Help Reddit Community | Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)