Pergunta

Eu preciso ler o número da conta do Maestro / Mastercard com leitor de cartão inteligente. Eu estou usando Java 1.6 e seu pacote javax.smartcardio. Eu preciso enviar comando APDU que irá pedir a aplicação EMV armazenados no chip do cartão para o número PAN. O problema é que não consigo encontrar array de bytes regular para construir comando APDU que irá retornar os dados necessários em qualquer lugar ...

Foi útil?

Solução

Você não deve precisar para embrulhar o APDU ainda mais. A camada API deve tomar cuidado com isso.

Parece que a resposta 0x6D00 apenas significa que a aplicação não suportam o INS.

Apenas solução de problemas agora, mas você se começar por selecionar a aplicação MasterCard, certo?

i. algo como isto:

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

Outras dicas

aqui é algum exemplo de trabalho:

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

Isso funciona com cartão Maestro, eu posso ler número PAN, mas agora eu preciso ler número PAN da MasterCard. Eu não sei o que eu deveria mudar o registro de leitura APDU ou selecione APDU aplicação. Qualquer pessoa familiarizada com 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();

Você precisa fazer construir um objeto CommandAPDU e passá-lo para a transmissão (.) - comando

Você deve ser capaz de encontrar o comando precisa na documentação para o seu smartcard, mas aqui está um exemplo:

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

Você tentou olhando para cima na documentação que significa 0x6D00? Parece que isso pode significar que o comando ENVELOPE não é suportado. Você já tentou usar protocolo T = 0 em vez de T = 1?

Eu não esperaria que o meu exemplo para o trabalho em seu cartão. Eu não sei qual APDUs os MasterCard-suportes Maestro /, então eu não poderia dar-lhe um exemplo de trabalho.

Tente dar o comando de uma duração prevista explícita como esta:

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

que sobre usando um scanner, obter uma imagem do cartão, a digitalização do conteúdo da imagem com uma biblioteca boa java ocr (como http://ocr4j.sourceforge.net/ por exemplo) e procurar por um (normalmente) seqüência de 16 dígitos XXXX-XXXX-XXXX-XXXX, então você vai ter o PAN a partir de qualquer cartão EMV usando java.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top