JavaCard: CC51B / Carlos Castillo (ChaTo)

El siguiente es el informe final sobre el tema JavaCard, para el curso Arquitectura de Computadores; el preinforme también está disponible.

La tecnología JavaCard tiene por objeto permitir el desarrollo de aplicaciones en Java que puedan ser usadas en tarjetas inteligentes. Las principales complicaciones tienen que ver con lo limitado de los recursos de hardware, mientras que las ventajas se relacionan con la posibilidad de ocupar un lenguaje de alto nivel en un ambiente en que lo usual es programar en algún tipo de assembler difícil de depurar.

Notemos que esto último en particular constituye un fuerte cambio de paradigma. Cuando los recursos son escasos, la tendencia de la mayoría de los programadores es utilizar lenguajes de bajo nivel para controlar de mejor manera como se hacen las optimizaciones. Sin embargo, esto no considera posibles mejoras tecnológicas que pueden llegar a ser bastante rápidas.

Dichas mejoras tecnológicas son difíciles de seguir e implican grandes costos en modificaciones al software creado.La API de JavaCard es relativamente estable respecto a los cambios en los microprocesadores en miniatura usados.

Tarjetas inteligentes

Existen dos tipos básicos de tarjetas: unas son las tarjetas que simplemente tienen una banda magnética, y otras son las que incorporan un chip.

De estas últimas, existen a su vez dos subclases: las tarjetas de memoria y las tarjetas inteligentes. La diferencia es que el segundo tipo contiene un pequeño microprocesador para hacer calculos en los datos almacenados localmente.

La idea obvia detrás del uso de una tarjeta que incluya un microprocesador es que ésta es capaz de usar algún protocolo de comunicación segura al encriptar y decriptar mensajes en la tarjeta. Se piensa que se usen no sólo con los usos comunes de una tarjeta de crédito, sino que también para permitir autentificación segura a través de internet. Además, una tarjeta magnética de memoria tiene un espacio de sólo 140 bytes disponible, lo cual es largamente superado por una tarjeta basada en un chip.

Las tarjetas inteligentes consisten de una interfaz de comunicaciones, una memoria y una CPU. No poseen fuente de poder, teclado o pantalla. Tampoco tienen reloj, puesto que la señal de reloj es provista por el terminal.

Java Rings

El JavaRing es una variante de la idea de la tarjeta inteligente, que incluye un procesador con su propio reloj y fuente de poder, incluye un exponenciador con módulo por hardware para acelerar el algoritmo RSA (y una licencia de RSA para que la compra de un dispositivo JavaRing incluya una licencia para RSA de por vida); y tiene una interfaz de dos pins (DATA y GND). Además, se ocupa NVRAM (Non-volatile Random Access Memory) que tiene todas las ventajas de una RAM no volátil, mantenida por una pila de litio de 10 años de duración, y sin la desventaja de experimentar desgaste como las EEPROM.

La tecnología usada se llama iButton y ha sido usado por la empresa fabricante, Dallas Semiconductors, para hacer pequeños dispositivos de memoria no-volátil, que son utilizados actualmente en grandes cantidades. Por ejemplo, se utilizan como aros en la empresa ganadera para mantener un historial de las vacunas de cada animal.

El desarrollo del Crypto iButton fue un efecto colateral del desarrollo de chips para los servicios postales estadounidenses y tenía un pequeño sistema operativo. Aquí comienza la experiencia de Dallas en seguridad de datos.

Al salir JavaCard, la idea de migrar al nuevo sistema operativo era muy atractiva y eso se hizo. El resultado de la aplicación de iButtons que corrían una JCVM fue JavaRing.

Interfaz de comunicaciones

La interfaz de comunicaciones está hecha para comunicarse con un dispositivo que acepte tarjetas (CAD - Card Acceptance Device) a través de un conjunto de 8 pines.

La tarjeta sólo reacciona a los requerimientos de datos externos, nunca inicia por sí sola una comunicación. Todo el protocolo de comunicaciones, dimensiones, resistencia, etc, está claramente establecido en el estándar ISO-7816-3.

Estableciendo la conección

El handshake entre el terminal y la tarjeta tiene varias operaciones consecutivas:

A nivel físico, lo usual es un modo asíncrono half-duplex.

APDU

El mecanismo de envío y recepción es a través de un formato de paquetes llamados APDU (Application Protocol Data Units).

Existen dos tipos de APDU, de comando o de respuesta, con distintos formatos:

APDU de Comandos

Consta de 6 campos:

APDU de Respuesta

Consta de 3 campos:

La idea de la palabra de estado, es reportar códigos de retorno en el caso de que se produzcan errores o excepciones.

CPU

Incluso con los grandes avances, las tarjetas inteligentes tienen CPUs de 8 bits, lentas y sin facilidades en hardware para multitasking ni memoria virtual. Esto representa para el programador encontrarse con un ambiente de hardware similar al que era el estándar 15 años atrás.

Memoria

Hay tres tipos de memoria en una tarjeta:

Memoria ROM

Es una memoria no-volátil, sólo de lectura, que contiene el código y los datos permanentes; se graba en la fábrica. En el caso de los JavaRings, contiene un identificador único para cada iButton.

Memoria RAM

Es una memoria volátil y rápida. Se usa para mantener el stack y los datos temporales. Su disponibilidad es bastante limitada.

Memoria EEPROM

La memoria EEPROM es similar a la ROM, con la diferencia de que con algo de tiempo extra se puede re-escribir. Es una memoria lenta, pero persistente. A este nivel, cumple una función similar a la que tiene el disco duro en un computador normal.

Otra opción para lograr el mismo efecto de memoria no-volátil es usar una NVRAM, que requiere un suministro constante, aunque pequeño, de electricidad.

Una gran limitación de la EEPROM es que sufre de desgaste y con la tecnología disponible un bit después de 100,000 escrituras o más deja de ser confiable.

Especificaciones para una JavaCard

Una JavaCard debe tener al menos:

Sin embargo, estos son estándares mínimos. GemPlus provee de una tarjeta con las siguientes especificaciones:

Y un JavaRing estándard:

La JavaCard Virtual Machine

La principal diferencia entre la JCVM y la JVM (Java Virtual Machine) es que en JavaCard la aplicación se ejecuta en parte en el CAD (host) y en parte en la tarjeta.

La parte de la ejecución que ocurre fuera de la tarjeta implica la preparación del programa en un JavaCard Converter, el cual hace el trabajo que tiene relación con preparar las clases, resolver referencias, etc. Es como un pre-procesador.

La segunda parte es la ejecución de los bytecodes (el assembler de Java) en la tarjeta.

Relación con Java

Lo que se pierde respecto a Java

Algunas de las cosas que se mantienen

Algo nuevo

El uso de un PIN (Personal Identification Number) es ampliamente usado en tarjetas inteligentes. Se provee de un PIN que debe ser ingresado por el usuario para evitar que alguien utilice una tarjeta robada; este PIN corresponde al rol del código secreto en las tarjetas magnéticas de débito usadas en los cajeros automáticos.

Después de ingresar varias veces un PIN incorrecto, la JCVM entra en un estado halt del que solo puede salir si es llevada la tarjeta a la persona que emitió la tarjeta; los JavaRing implementan rapid zeroization para borrar el contenido de su NVRAM casi instantáneamente (esto no parece una gran maravilla tampoco, puesto que aparentemente basta con cortar el suministro de energía).

Limitaciones extra

Por eficiencia, se admite un máximo de 127 metodos en cada clase, incluyendo los metodos heredados. Además, no pueden haber más de 255 bytes en variables de instancia.

El estándard de JavaCard permite explícitamente que se realicen expansiones de la capacidad dispuesta en la API, siempre que se mantenga cierta compatibilidad hacia atrás. Por ejemplo, se asume que en algún momento algunas de las JavaCard van a implementar Garbage Collection, pero no se obliga a que todas lo tengan.

Toda extensión de javacard que se haga tiene que tener al mismo tiempo un conjunto de clases provistas por el fabricante que permitan manejar esas extensiones.

Uso del software para acomodarse al hardware

Aun cuando lo normal en Java es crear un nuevo objeto para varias operaciones, por ejemplo, para arrojar una excepción, en JavaCard dado que no hay recolección de basura y existe una buena posibilidad de quedarse sin memoria, se prefiere mas bien tener un objeto de cada clase e irlo cambiando durante la ejecución del programa.

Manejo de zonas criticas

Dado que existe una alta probabilidad de que una transacción quede a medio camino y por el uso normal (para manejo de dinero) que se hace de estas tarjetas, la integridad de los datos es un asunto crucial.

Para ello, existen las funciones System.beginTranscation() y System.commitTransaction(), junto a funciones de rollback incorporadas en la tarjeta que aseguran que una operación no sea interrumpida incorrectamente si el usuario, por ejemplo, retira la tarjeta del terminal.

Cuando queda una operación pendiente, la próxima conección de la tarjeta a un CAD hace que se invoque a los procedimientos de RollBack.

El sistema de archivos

El sistema de archivos contempla dos tipos de archivo, de acuerdo a lo indicado en la normativa ISO 7816-4

Un archivo elemental contiene referencias a arreglos de bytes, mientras que un archivo dedicado contiene colecciones de archivos elementales, como un directorio. Además de los dos anteriores, los chipcard de IBM proveen de un Archivo Maestro (MF - Master File) que corresponde al directorio raíz del sistema de archivos.

Cuando se usa un EF, la JCVM referencia al arreglo de bytes y no intenta pedir nuevo espacio para lo que está escribiendo.

En principio, no existía soporte nativo para records en los archivos, y todo tiene que interpretarse por software. Un archivo es un conjunto de bytes solamente (archivo transparente). Sin embargo, se provee en la API de la versión 2.0 varios tipos de archivo de registros:

Existen dos tipos de archivo: lineales (un listado de registros) y cíclicos (un anillo de registros). Los archivos lineales a su vez pueden ser con registros de largo fijo o de largo variable.

Un archivo cíclico tiene un número fijo de slots que se determina al momento de crearlo. Una vez que se llena, el registro más nuevo sobreescribe al más antiguo en el archivo.

Un archivo puede tener hasta 127 registros y ninguno de ellos puede sobrepasar los 255 bytes.

Seguridad de datos

Existe soporte para encriptación simétrica y asimétrica (de llave pública), con mecanismos para autentificación y protección de datos. Esto es crucial porque es el uso más obvio de estos dispositivos.

En los JavaRings, la seguridad tanto física como lógica es crucial, y la memoria NVRAM del chip se borra rápidamente al detectarse cualquier intento de violación del chip. Además, físicamente el chip está encerrado en una carcaza de acero inoxidable que está unida de manera que no se puede abrir sin borrar la memoria.

Finalmente, y prácticamente en el terreno de la paranoia, el reloj de la CPU es inestable y varía de 10 a 20MHz, de manera que es imposible sincronizarse con él al atacar la CPU (incluso invulnerable a los time-attacks), esto en todo caso implica que hay que tener otro reloj estable (de 32Khz) para mantener la hora del día bien actualizada.

A pesar de que no es un requerimiento, Sun recomienda a los fabricantes que los dispositivos que implementen la plataforma JavaCard, que provean de medios de acelerar por hardware el cálculo de exponenciaciones con módulo. Esto consigue calcular exponentes de 1024 bits en 1 segundo, en el caso de los JavaRings, y en 0.4 segundos en los chipcards de la IBM.

Fuentes de información




Carlos Castillo - chato@usa.net