Ir para o conteúdo
Idioma: PT

O que é uma APDU, e quando o seu código precisa de uma?

Uma APDU é a unidade de comando e resposta da ISO/IEC 7816-4. Um comando carrega quatro bytes de cabeçalho, CLA, INS, P1 e P2, depois dados opcionais e um tamanho esperado; a resposta carrega dados e dois bytes de estado. O código precisa de uma para as tags Tipo 4 e para os cartões, por IsoDep no Android ou NFCISO7816Tag no iOS.

Comando e resposta

Uma APDU de comando começa com quatro bytes. CLA dá a classe da instrução, INS a própria instrução, P1 e P2 os parâmetros dela. Os dados vêm depois quando o comando envia algum, precedidos do tamanho deles, Lc, e o comando pode terminar com Le, o tamanho da resposta que ele espera. O inicializador do NFCISO7816APDU da Apple monta uma exatamente com esses campos.

Os tamanhos vêm em duas medidas. Uma APDU padrão carrega no máximo 255 bytes de dados, 261 bytes ao todo, e uma estendida até 65535, segundo a referência do IsoDep, e alguns controladores Android recusam a forma estendida, como explica a página dos limites do controlador. O inicializador da Apple codifica Le a partir de um número: 256 envia 00 na forma curta, 65536 envia 0000 na forma estendida, e -1 declara que nenhum dado de resposta é esperado.

A resposta são dados seguidos de dois bytes de estado, SW1 e SW2. Os dados podem estar vazios, e a Apple observa que podem estar vazios mesmo quando o comando deu certo.

Quando o código precisa de uma

Sempre que a tag fala ISO/IEC 7816-4: as tags Tipo 4, que guardam NDEF em arquivos alcançados por APDU, e os cartões construídos sobre a ISO/IEC 14443-4, que o Android expõe por IsoDep. Uma tag Tipo 2 não fala; ela responde aos comandos NFC-A descritos na página da memória Tipo 2.

No Android, IsoDep.transceive() envia a APDU e devolve a resposta com os dois bytes de estado dela no fim. No iOS, uma sessão de tag entrega NFCISO7816Tag e o sendCommand(apdu:) dele; para as tags MIFARE Plus e DESFire entregues como NFCMiFareTag, a Apple oferece sendMiFareISO7816Command para o mesmo fim.

Ler ou gravar NDEF numa tag Tipo 4 não exige APDU montada à mão: a classe Ndef do Android e as chamadas NDEF do Core NFC fazem isso. O código monta APDU para o que o NDEF não cobre, como um arquivo que não seja o arquivo NDEF, uma condição de acesso, ou uma aplicação própria. A página do arquivo NDEF Tipo 4 acompanha a sequência que as plataformas executam.

A seleção vem primeiro

Um cartão ISO/IEC 7816-4 guarda aplicações e arquivos, e um comando age sobre o que está selecionado no momento. SELECT, instrução 0xA4, escolhe por nome quando P1 é 0x04, sendo o nome um identificador de aplicação, e por identificador de arquivo quando P1 é 0x00. Esses são os valores que a pilha NFC de código aberto do Android usa para alcançar o NDEF numa tag Tipo 4.

O iOS restringe a primeira forma. Um SELECT com P1 em 0x04 tem de nomear uma aplicação listada no Info.plist do aplicativo, senão a chamada falha com readerErrorSecurityViolation, segundo a referência do sendCommand. A sessão também seleciona uma das aplicações listadas quando descobre a tag, e informa qual em initialSelectedAID; a página das declarações cobre a lista.

Uma seleção não dura mais do que a energia da tag. Uma tag que sai do campo perde as duas, então o código que reconecta seleciona a aplicação de novo antes do comando seguinte dele.

Ler os bytes de estado

90 00 quer dizer que o comando foi concluído. Os outros valores vêm da ISO/IEC 7816-4 ou da aplicação do cartão, e a pilha do Android nomeia aqueles que um leitor Tipo 4 encontra com mais frequência:

Bytes de estado nomeados na pilha NFC do Android
SW1 SW2Significado
90 00Comando concluído
6A 82Arquivo ou aplicação não encontrado
67 00Tamanho errado
69 86Comando não permitido
6B 00Parâmetros errados
6D 00Instrução não suportada
6E 00Classe não suportada

Cada plataforma os esconde do jeito dela. No Android eles são os dois últimos bytes do vetor que transceive() devolve, e o código que trata o vetor inteiro como dados os confunde com conteúdo. No iOS o erro cobre apenas a comunicação, e um aplicativo que confere o erro e não sw1 e sw2 toma uma recusa por um sucesso.

Perguntas frequentes

Uma tag Tipo 2 usa APDU?

Não. Ela responde a comandos NFC-A como READ e WRITE; as APDU pertencem às tags Tipo 4 e aos cartões construídos sobre a ISO/IEC 14443-4.

Por que o iOS recusa o meu comando SELECT?

Um SELECT por identificador de aplicação tem de nomear um identificador listado no Info.plist. Senão o Core NFC falha a chamada com readerErrorSecurityViolation.

O que quer dizer 6A 82?

Que o arquivo ou a aplicação nomeada no comando não foi encontrada. Depois de um SELECT da aplicação NDEF, quer dizer que a tag não tem nenhuma.

Uma APDU é criptografada?

Não pelo formato dela. A proteção, onde um cartão tem alguma, é definida pela aplicação do cartão e descrita na ficha técnica do chip.