Saltar al contenido
Idioma: ES

¿Qué es una APDU, y cuándo la necesita tu código?

Una APDU es la unidad de comando y respuesta de la ISO/IEC 7816-4. Un comando lleva cuatro bytes de cabecera, CLA, INS, P1 y P2, después datos opcionales y una longitud esperada; la respuesta lleva datos y dos bytes de estado. El código necesita una para las etiquetas de tipo 4 y para las tarjetas.

Comando y respuesta

Un comando APDU empieza por cuatro bytes. CLA da la clase de la instrucción, INS la instrucción misma, P1 y P2 sus parámetros. Los datos van detrás cuando el comando envía alguno, precedidos de su longitud, Lc, y el comando puede terminar con Le, la longitud de la respuesta que espera. El inicializador de NFCISO7816APDU de Apple construye uno a partir de exactamente esos campos.

Las longitudes vienen en dos tamaños. Una APDU normal lleva como mucho 255 bytes de datos, 261 en total, y una extendida hasta 65535, según la referencia de IsoDep, y algunos controladores de Android rechazan la forma extendida, como explica la página de los límites del controlador. El inicializador de Apple codifica Le a partir de un número: 256 envía 00 en la forma corta, 65536 envía 0000 en la extendida, y -1 declara que no se espera ningún dato de respuesta.

La respuesta son datos seguidos de dos bytes de estado, SW1 y SW2. Los datos pueden estar vacíos, y Apple señala que pueden estarlo incluso cuando el comando salió bien.

Cuándo la necesita el código

Siempre que la etiqueta hable ISO/IEC 7816-4: las etiquetas de tipo 4, que guardan el NDEF en archivos a los que se llega con APDU, y las tarjetas construidas sobre la ISO/IEC 14443-4, que Android expone mediante IsoDep. Una etiqueta de tipo 2 no; responde a los comandos NFC-A que describe la página de la memoria de tipo 2.

En Android, IsoDep.transceive() envía la APDU y devuelve la respuesta con sus dos bytes de estado al final. En iOS, una sesión de etiqueta entrega NFCISO7816Tag y su sendCommand(apdu:); para las etiquetas MIFARE Plus y DESFire entregadas como NFCMiFareTag, Apple ofrece sendMiFareISO7816Command con el mismo fin.

Leer o escribir NDEF en una etiqueta de tipo 4 no exige ninguna APDU construida a mano: la clase Ndef de Android y las llamadas NDEF de Core NFC lo hacen. El código construye APDU para lo que el NDEF no cubre, como un archivo distinto del archivo NDEF, una condición de acceso, o una aplicación propia. La página del archivo NDEF de un tipo 4 sigue la secuencia que ejecutan las plataformas.

La selección va primero

Una tarjeta ISO/IEC 7816-4 contiene aplicaciones y archivos, y un comando actúa sobre lo que está seleccionado en ese momento. SELECT, instrucción 0xA4, elige por nombre cuando P1 es 0x04, siendo el nombre un identificador de aplicación, y por identificador de archivo cuando P1 es 0x00. Son los valores que usa el código abierto de la pila NFC de Android para llegar al NDEF de una etiqueta de tipo 4.

iOS restringe la primera clase. Un SELECT con P1 puesto a 0x04 tiene que nombrar una aplicación enumerada en el Info.plist de la aplicación, si no la llamada falla con readerErrorSecurityViolation, según la referencia de sendCommand. La sesión selecciona además una de las aplicaciones enumeradas al descubrir la etiqueta, y declara cuál en initialSelectedAID; la página de las declaraciones cubre la lista.

Una selección no dura más que la energía de la etiqueta. Una etiqueta que sale del campo pierde las dos, así que un código que se reconecta vuelve a seleccionar la aplicación antes de su comando siguiente.

Leer los bytes de estado

90 00 quiere decir que el comando se completó. Los demás valores salen de la ISO/IEC 7816-4 o de la aplicación de la tarjeta, y la pila de Android nombra los que un lector de tipo 4 se encuentra más a menudo:

Bytes de estado nombrados en la pila NFC de Android
SW1 SW2Significado
90 00Comando completado
6A 82Archivo o aplicación no encontrados
67 00Longitud incorrecta
69 86Comando no permitido
6B 00Parámetros incorrectos
6D 00Instrucción no admitida
6E 00Clase no admitida

Cada plataforma los esconde a su manera. En Android son los dos últimos bytes del array que devuelve transceive(), y un código que trata el array entero como datos los confunde con contenido. En iOS el error cubre solo la comunicación, y una aplicación que mira el error y no sw1 y sw2 toma un rechazo por un éxito.

Preguntas frecuentes

¿Una etiqueta de tipo 2 usa APDU?

No. Responde a comandos NFC-A como READ y WRITE; las APDU pertenecen a las etiquetas de tipo 4 y a las tarjetas construidas sobre la ISO/IEC 14443-4.

¿Por qué iOS rechaza mi comando SELECT?

Un SELECT por identificador de aplicación tiene que nombrar un identificador enumerado en Info.plist. Si no, Core NFC hace fallar la llamada con readerErrorSecurityViolation.

¿Qué quiere decir 6A 82?

Que el archivo o la aplicación nombrados en el comando no se encontraron. Tras un SELECT de la aplicación NDEF, quiere decir que la etiqueta no tiene ninguna.

¿Una APDU va cifrada?

No por su formato. La protección, donde una tarjeta tenga alguna, la define la aplicación de la tarjeta y la describe la hoja de datos del chip.