Comment puis-je lire le PAN d'une carte à puce EMV de Java

je dois lire le numéro de compte de Maestro/Mastercard avec lecteur de carte à puce. J'utilise la version 1.6 de Java et de ses javax.paquet smartcardio. Je dois envoyer la commande APDU qui demandera application EMV stocké sur la puce de la carte pour le numéro de PAN. Le problème est que je ne peux pas trouver de tableau octet régulier pour construire la commande APDU qui retournera les données nécessaires n'importe où...

9
demandé sur Rasmus Faber 2008-11-12 10:32:14

6 réponses

vous ne devriez pas avoir besoin d'envelopper L'APDU plus loin. La couche API devrait s'en occuper.

il semble que la réponse 0x6D00 signifie simplement que l'application n'a pas supporté L'INS.

vient de dépanner maintenant, mais vous avez commencé par sélectionner L'application MasterCard, n'est-ce pas?

i. e. quelque chose comme ceci:

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();
}
6
répondu Rasmus Faber 2008-11-14 10:51:59

voici un exemple pratique:

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

cela fonctionne avec Maestro card, je peux lire le numéro PAN, mais maintenant je dois lire le numéro PAN de MasterCard. Je ne sais pas si je dois changer le fichier de lecture APDU ou sélectionner application APDU. Quiconque est familier avec les unités apdu?

3
répondu 2008-11-20 07:53:37
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();
1
répondu egrunin 2010-08-11 00:12:27

vous devez construire un objet CommandAPDU et le passer à la commande transmit () -.

vous devriez pouvoir trouver la commande précise dans la documentation de votre carte à puce, Mais voici un exemple:

byte[] readFile(CardChannel channel) throws CardException {
  CommandAPDU command = new CommandAPDU(0xB0, 0x60, 0x10, 0x00);
  ResponseAPDU response = channel.transmit(command);
  return response.getData();
}
0
répondu Rasmus Faber 2008-11-12 09:50:50

avez-vous cherché dans votre documentation ce que 0x6D00 signifie? Il semble que cela signifie que la commande enveloppe n'est pas supportée. Avez-vous essayé le protocole T=0 au lieu de T=1?

Je ne m'attends pas à ce que mon exemple fonctionne sur votre carte. Je ne sais pas quel APDUs le Maestro/MasterCard-supporte, donc je ne pouvais pas vous donner un exemple de travail.

essayez de donner à la commande une longueur attendue explicite comme ceci:

byte[] readPan(CardChannel channel) throws CardException {
  CommandAPDU command = new CommandAPDU(0x00, 0xB2, 0x5a, 0x14, 250);
  ResponseAPDU response = channel.transmit(command);
  return response.getData();
}
0
répondu Rasmus Faber 2008-11-12 12:14:16

qu'en est-il de l'utilisation d'un scanner, obtenir une image de la carte, scanner le contenu de l'image avec une bonne bibliothèque ocr java ( comme http://ocr4j.sourceforge.net / par exemple ) et rechercher une séquence à 16 chiffres (généralement) XXXX-XXXX-XXXX-XXXX , vous obtiendrez alors le PAN de n'importe quelle carte EMV en utilisant java.

-2
répondu 2014-08-08 11:18:14