Смарт карти и рамката OpenCard

Предишният разработчик на Javaколона „Смарт карти: буквар“, дава общ преглед на смарт картите и как работят. Той включваше раздел за стандартите за смарт карти, представящ концепцията за OpenCard. Както е описано в първата статия, OpenCard е отворен стандарт, който осигурява оперативна съвместимост на приложения за смарт карти в NC, POS терминали, настолни компютри, лаптопи, комплекти и PDA. OpenCard може да предостави 100% чисти приложения за смарт карти на Java. Приложенията за смарт карти често не са чисти, защото комуникират с външно устройство или използват библиотеки на клиента. В тази статия ще предоставим две реализации на два различни четци на карти, демонстрирайки как бихте добавили поддръжка за четци на карти към OpenCard. Надяваме се, че портовете за Litronic, Gemplus, Schlumberger, Bull, Toshiba и SCM ще бъдат налични скоро, комплименти на OpenCard иJavaWorld .

Въведение

За да използвате смарт карта, трябва да можете да четете картата и да комуникирате с нея с помощта на приложение. OpenCard предоставя рамка за това, като определя интерфейси, които трябва да бъдат внедрени. Рамката OpenCard дефинира няколко от тези интерфейси. След като тези интерфейси бъдат внедрени, можете да използвате други услуги в горните слоеве на API. Например, с правилно свързан четец, OpenCard може да стартира агент на Java карта, когато картата е поставена. След това агентът на картата може да комуникира с приложения на смарт картата чрез терминала на картата в контекста на сесия.

Тази статия ще ви научи как да свързвате терминали на карти с OpenCard. В бъдещите статии ще се обсъжда как да се напише агент. Осигурено е малко тестово приложение, което получава ATR (Answer to Reset) низ. ATR е от основно значение за смарт картите. Ще вземем комплекта за разработка на OpenCard и ще обясним внедряванията за два различни четци на смарт карти, използвайки Card Terminal Interface. Техниките, обсъдени в статията за захранване на четци, стартиране на сесии с карти и използването на единици за данни за протокол и единици за данни за протокол от приложения, могат да бъдат използвани повторно за повечето от четците на пазара.

Въпреки че не е необходимо да се използва OpenCard при създаването на 100% чисти приложения за смарт карти Java, без него разработчиците са принудени да използват домашно отгледани интерфейси за смарт карти. (За подробно обяснение какво всъщност означава 100% чистота вижте раздела Ресурси.) OpenCard също така предоставя на разработчиците интерфейс към PC / SC (интерфейс за приложение на смарт карти, разработен от Microsoft и други за комуникация със смарт карти от базиран на Win32 платформи за персонални компютри) за използване на съществуващи устройства на платформи Win32. Прочетете и научете как да използвате смарт карти с вашия браузър.

Архитектура на OpenCard: Общ преглед

OpenCard предоставя архитектура за разработване на приложения в Java, които използват смарт карти или други устройства, съвместими с ISO 7816, на различни целеви платформи като Windows, мрежови компютри, Unix работни станции, Webtops, зададени върхове и т.н. OpenCard Framework предоставя интерфейс за приложно програмиране (API), който ви позволява да регистрирате карти, да търсите карти в четци и по избор да стартирате Java агенти, когато картите се вмъкнат в четеца. Архитектурата на OpenCard е изобразена на фигура 1.

Архитектурата на Рамката OpenCard се състои от CardTerminalтова CardAgent, агентите и / или приложения, които взаимодействат с тези компоненти. OpenCard се състои от четири Java пакета с префикс opencard :

  1. приложение
  2. io
  3. агент
  4. терминал

Терминалният пакет в OpenCard

Пакетите opencard.application и opencard.io предоставят API на високо ниво, използван от разработчика на приложението. Услугите, необходими на API на високо ниво, се извършват по класове в пакетите opencard.agent и opencard.terminal . Пакетът opencard.agent абстрахира функционалността на смарт картата чрез CardAgent. Пакетът opencard.terminal абстрахира терминалите на картите (известни също като четци на карти ). Разбирането на структурата на пакета opencard.terminal е необходимо, за да се разберат примерните реализации на терминали за карти, предоставени в тази статия.

Терминал за карта абстрахира устройството, което се използва в компютърна система за комуникация със смарт карта. Пакетът opencard.terminal съдържа класове за представяне на хардуера на терминала на карта, за взаимодействие с потребителя и за управление на ресурси на терминал за карта. Не всички читатели имат тези способности. Когато прилагаме четец, който няма въвеждане от клавиатурата, ще използваме UserInteractionHandler.

Представяне на картовия терминал

Всеки терминал на карта е представен от екземпляр от клас, CardTerminalкойто дефинира абстрактния терминал, съвместим с OpenCard. Терминалът за карти може да има един или повече слота за смарт карти и по избор дисплей и клавиатура или ПИН подложка. Слотовете на картовия терминал са представени от екземпляри на абстрактния клас Slot, който предлага методи за изчакване на вмъкването на карта, за комуникация с картата и за изваждането й (ако е възможно).

Взаимодействие с потребителя

Използването на смарт карта изисква взаимодействие с потребителя - за проверка на притежателя на картата. Интерфейсът UserInteractionосигурява тази функционалност. Той предоставя методи за писане на съобщение на дисплея и получаване на входни данни от потребителя. Картовите терминали, които не поддържат всички функции за взаимодействие с потребителя, могат да се възползват от UserInteractionHandler, който реализира a UserInteractionкато графичен потребителски интерфейс, базиран на абстрактния набор от инструменти за прозорци (AWT).

Управление на ресурси

Картите и четците на карти изискват управление на ресурсите, така че агентите да могат да получат необходимото ниво на контрол на достъпа. Управлението на ресурсите осигурява споделяне на терминали на карти и вмъкнати в тях карти между агентите в системата. Например, да кажем, че използвате смарт картата си, за да подпишете документ едновременно с появата на високоприоритетно имейл съобщение, което трябва да бъде декодирано с помощта на вашата смарт карта. Управлението на ресурси арбитрира достъпа до CardTerminalи правилния порт.

Управлението на ресурси за терминали на карти се постига от CardTerminalRegistryкласа на OpenCard. Има само един екземпляр на CardTerminalRegistry: системния регистър на терминални карти. Регистърът на терминалите за карти в цялата система проследява инсталираните в системата терминали за карти. Регистърът на картовия терминал може да бъде конфигуриран от свойства при стартиране на системата или динамично чрез registerи unregisterметоди за динамично добавяне или премахване на терминали на карти от регистъра.

По време на регистрацията на картов терминал CardTerminalFactoryе необходим a, за да се създаде екземпляр на съответния клас на изпълнение за терминала на картата. Фабриката на терминала за карти използва името на типа и типа на конектора на терминала за карта, за да определи CardTerminalкласа, който да се създаде. Концепцията за фабрика за картови терминали позволява на производителя на картови терминали да дефинира съпоставяне между лесни за ползване имена на типа и име на клас.

Примерно внедряване: терминал на IBM карта

В този раздел ще опишем интеграцията на терминала за карта IBM 5948 в OpenCard. Терминалът за карта IBM 5948 има един слот за смарт карти, LCD дисплей и ПИН подложка. Той е свързан към работната станция или компютър чрез сериен порт. Повече информация за този четец е достъпна в

Ресурси

раздел.

За да получите достъп до терминал карта от рамките OpenCard, за прилагане на двете абстрактни класове CardTerminalи Slotтрябва да бъде предоставена. Те са именувани IBM5948CardTerminalи IBM5948Slotсъответно. Освен това е необходимо подходящо CardTerminalFactoryиме IBMCardTerminalFactory. Терминалната реализация се състои от пакет com.ibm.zurich.smartcard.terminal.ibm5948 . Фигура 2 изобразява връзките за наследяване между класовете на opencard.terminal , класовете Java и изпълнението на терминала. Диаграмата на класовете също съдържа клас IBM5948Driver, който не реализира никакъв абстрактен клас на OpenCard, но служи като Java интерфейс към библиотеката на драйвера на терминала, написана на C.

We assume that the terminal is already connected to the workstation or PC, and that the serial port is configured to work with the terminal. In the following section, we describe the design and implementation of the driver, the terminal, the slot, and the card terminal factory. The configuration of the card terminal registry also is provided.

The card terminal driver

The card terminal is shipped with a driver that is available as a dynamic link library (DLL). The DLL has a C API that offers the functions CT_init, CT_data, and CT_close:

  • The function CT_init is used to open a connection to a card terminal that is connected to a certain serial port. After the connection has been established, protocol data units (PDU) can be exchanged with the card terminal and APUs can be exchanged with the smart card that is plugged into the slot of the terminal via the CT_data function.

  • The CT_data call is used to send one PDU and retrieve the response from the terminal or the smart card, respectively.

  • The CT_close function is used to close the connection to the card terminal and release any resources.

Success or failure of all three API calls is indicated by the return code.

The Java API

Similar to the C API, we define a Java API for the card terminal driver. The Java API for the card terminal consists of class IBM5948Driver, which has native methods calling the C API. We decided to implement as much functionality as possible in Java and have only some "glue" code written in C. In fact, the parameters of the ctInit and ctClose method are just passed on to the respective C API function. Since arrays are organized differently in C and Java, they need to be handled by calls to the Java Native Interface (JNI) API of the virtual machine. The native methods return the return code of the C API. The implementation of the ctData method is shown below:

JNIEXPORT jint JNICALL Java_com_ibm_zurich_smartcard_terminal_ibm5948_IBM5948Driver_ctData(JNIEnv *env, jobject that, jbyte destination, jbyteArray command, jint commandLength, jbyteArray response, jint responseMax) { short rc; unsigned char sad = HOST; unsigned char dad = destination; unsigned short responseLength = (unsigned short)responseMax; unsigned char *commandArray; unsigned char *responseArray; jclass cls = (*env)->GetObjectClass(env, that); jfieldID fid; jint ctn; fid = (*env)->GetFieldID(env, cls, "ctNumber", "I"); if(fid == NULL) { return(CT_ERR_HTSI); } ctn = (*env)->GetIntField(env, that, fid); commandArray = (unsigned char *) (*env)->GetByteArrayElements(env, command, 0); responseArray = (unsigned char *) (*env)->GetByteArrayElements(env, response, 0); rc = CT_DATA(ctn, &dad, &sad, commandLength, commandArray, &responseLength, responseArray); (*env)->ReleaseByteArrayElements(env, command, (signed char *)commandArray, 0); (*env)->ReleaseByteArrayElements(env, response, (signed char *)responseArray, 0); fid = (*env)->GetFieldID(env, cls, "responseLength", "I"); if(fid == NULL) { return(CT_ERR_HTSI); } (*env)->SetIntField(env, that, fid, responseLength); return rc; } 

The native methods described above mimic the C API in Java. The reason for this was to have as little C code to maintain as possible. On top of the native methods, which are private, the methods init, data, and close are implemented. They call the native methods and throw an exception if the return code indicates an error. In the case of the data method, the response byte array is returned upon a successful completion of the native method call. The example below shows the data method:

synchronized byte[] data(byte destination, byte[] pdu) throws CardTerminalException { int rc = ctData(destination, pdu, pdu.length, response, response.length); if (rc == CT_OK) { byte[] result = new byte[responseLength]; System.arraycopy(response, 0, result, 0, responseLength); return result; } else throw new CardTerminalException(rc2String(rc)); } 

In order to keep memory management inside Java, a buffer response for the answer from the terminal is allocated once and passed on to the native code. Since the C API is not re-entrant, the methods of IBM5948Driver must be declared synchronized.

Implementing the card terminal

Терминалът на картата се управлява чрез подаване на контролни PDU към метода за данни на IBM5948Driver. Форматът на контролните PDU е съвместим с ISO 7816-4. Това ни позволява да разположим клас opencard.agent.CommandPDUза конструиране на PDU и opencard.agent.ResponsePDUза обработка на отговорите.

В IBM5948CardTerminalкласа простира клас CardTerminal. Конструкторът инициализира супер класа и създава екземпляр на драйвера. След това създава екземпляр на масива, който да задържа слотовете, и създава екземпляр на един екземпляр на, за IBM5948Slotда представлява единствения слот на терминала на карта IBM 5948.