Domanda

Devo leggere il numero di conto da Maestro / Mastercard con lettore di smart card. Sto usando Java 1.6 e il suo pacchetto javax.smartcardio. Devo inviare il comando APDU che chiederà all'applicazione EMV memorizzata sul chip della scheda il numero PAN. Il problema è che non riesco a trovare un normale array di byte per costruire il comando APDU che restituirà i dati necessari ovunque ...

È stato utile?

Soluzione

Non dovresti aver bisogno di avvolgere ulteriormente l'APDU. Il livello API dovrebbe occuparsene.

Sembra che la risposta 0x6D00 significhi solo che l'applicazione non supporta INS.

Sto solo risolvendo i problemi ora, ma hai iniziato selezionando l'applicazione MasterCard, giusto?

vale a dire. qualcosa del genere:

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();
}

Altri suggerimenti

ecco un esempio funzionante:

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 );

Funziona con la carta Maestro, posso leggere il numero PAN, ma ora devo leggere il numero PAN della MasterCard. Non so se dovrei modificare il record di lettura APDU o selezionare l'applicazione APDU. Qualcuno che ha familiarità con le APDU?

atr = open();
prints(atr);

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);
prints(card_response);
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);
prints(card_response);
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);
prints(card_response);
// 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(card_response);
prints("[Step 5] Send GET PROCESSING OPTIONS command");

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

// 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);
prints(card_response);
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);
prints(card_response);

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

close();

Devi costruire un oggetto CommandAPDU e passarlo al comando transmission ().

Dovresti essere in grado di trovare il comando preciso nella documentazione per la tua smart card, ma ecco un esempio:

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

Hai provato a cercare nella tua documentazione cosa significa 0x6D00? Sembra che potrebbe significare che il comando ENVELOPE non è supportato. Hai provato a utilizzare il protocollo T = 0 anziché T = 1?

Non mi aspetto che il mio esempio funzioni sulla tua carta. Non so quali APDU siano supportati dal Maestro / MasterCard, quindi non potrei darvi un esempio funzionante.

Prova a dare al comando una lunghezza prevista esplicita come questa:

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

che ne dici di usare uno scanner, ottenere un'immagine della scheda, scansionare il contenuto dell'immagine con una buona libreria java ocr (come http://ocr4j.sourceforge.net/ per esempio) e cerca una sequenza (generalmente) di 16 cifre XXXX-XXXX-XXXX-XXXX, quindi otterrai il PAN da qualsiasi scheda EMV usando java.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top