Frage

Ich muss Kontonummer von Maestro / Mastercard mit Smartcard-Leser lesen. Ich bin mit Java 1.6 und seinem javax.smartcardio Paket. Ich brauche APDU-Befehl zu senden, die auf der Karte des Chip für PAN-Nummer gespeichert EMV-Anwendung fragen. Das Problem ist, ich nicht regelmäßig Byte-Array finden APDU-Befehl zu konstruieren, die benötigten Daten überall zurückkehren wird ...

War es hilfreich?

Lösung

Sie sollten nicht die APDU weiter wickeln müssen. Die API-Schicht sollte sich darum kümmern.

Es sieht aus wie die 0x6D00 Antwort bedeutet nur, dass die Anwendung nicht die IN unterstützen.

Fehlerbehebung Gerade jetzt, aber Sie haben durch die Auswahl der Mastercard-Anwendung beginnen, nicht wahr?

d. so etwas wie folgt aus:

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

Andere Tipps

hier einige Arbeitsbeispiele:

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

Dies funktioniert mit Maestro-Karte, kann ich PAN-Nummer, lesen Sie doch jetzt brauche ich von Mastercard PAN-Nummer zu lesen. Ich weiß nicht, soll ich die Lese Datensatz APDU oder wählen Anwendung APDU ändern. Wer mit APDUs?

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

Sie tun müssen, um ein CommandAPDU Objekt konstruieren und an den Sende () übergeben -. Befehl

Sie sollten in der Lage, den genauen Befehl in der Dokumentation für die Smartcard zu finden, aber hier sind ein Beispiel:

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

Haben Sie versucht, die oben schaut in Ihrer Dokumentation, was 0x6D00 bedeutet? Es sieht aus wie es bedeuten könnte, dass der ENVELOPE-Befehl nicht unterstützt wird. Haben Sie versucht, T = 0 Protokoll anstelle von T = 1?

mit

Ich würde nicht erwarten, dass mein Beispiel auf Ihrer Karte zu arbeiten. Ich weiß nicht, welche die Maestro / Mastercard-Träger APDUs, so konnte ich Ihnen nicht ein funktionierendes Beispiel geben.

Sie den Befehl eine explizite erwartete Länge wie diese geben:

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

, was über einen Scanner, ein Bild von der Karte erhalten, scannen den Inhalt des Bildes mit einer guten Java-ocr-Bibliothek (wie

scroll top