Kad pintar dan Rangka Kerja OpenCard

Pembangun Java sebelumnyalajur, "Kad pintar: Buku asas", memberikan gambaran umum mengenai kad pintar dan cara ia berfungsi. Ini merangkumi bahagian mengenai standard kad pintar, memperkenalkan konsep OpenCard. Seperti yang dijelaskan dalam artikel pertama, OpenCard adalah standard terbuka yang menyediakan interoperabilitas aplikasi kad pintar di seluruh NC, terminal POS, desktop, komputer riba, set top, dan PDA. OpenCard dapat menyediakan aplikasi kad pintar Java 100% tulen. Aplikasi kad pintar selalunya tidak suci kerana berkomunikasi dengan peranti luaran atau menggunakan perpustakaan pada pelanggan. Dalam artikel ini kami akan memberikan dua pelaksanaan kepada dua pembaca kad yang berbeza, menunjukkan bagaimana anda akan menambahkan sokongan untuk pembaca kad ke OpenCard. Kami berharap bahawa port untuk Litronic, Gemplus, Schlumberger, Bull, Toshiba, dan SCM akan segera tersedia, pujian dari OpenCard danJavaWorld .

Pengenalan

Untuk menggunakan kad pintar, anda perlu dapat membaca kad dan berkomunikasi dengannya menggunakan aplikasi. OpenCard menyediakan kerangka untuk ini dengan menentukan antara muka yang mesti dilaksanakan. Rangka kerja OpenCard menentukan beberapa antara muka ini. Setelah antara muka ini dilaksanakan, anda boleh menggunakan perkhidmatan lain di lapisan atas API. Sebagai contoh, dengan pembaca yang dihubungkan dengan betul, OpenCard dapat memulakan ejen kad Java setiap kali kad dimasukkan. Ejen kad kemudian dapat berkomunikasi dengan aplikasi pada kad pintar melalui terminal kad dalam konteks sesi.

Artikel ini akan mengajar anda cara menghubungkan terminal kad ke OpenCard. Artikel masa depan akan membincangkan cara menulis ejen. Aplikasi ujian kecil, yang mendapat rentetan ATR (Answer to Reset) disediakan. ATR adalah asas untuk kad pintar. Kami akan mengambil kit pengembangan OpenCard dan menerangkan pelaksanaan untuk dua pembaca kad pintar yang berbeza menggunakan Antaramuka Terminal Kad. Teknik yang dibincangkan dalam artikel untuk memberi tenaga kepada pembaca, memulakan sesi kad, dan penggunaan Unit Data Protokol dan Unit Data Protokol Aplikasi dapat digunakan kembali untuk kebanyakan pembaca di pasaran.

Walaupun tidak perlu menggunakan OpenCard dalam membuat 100% aplikasi kad pintar Java murni, tanpa itu pemaju terpaksa menggunakan antara muka buatan sendiri untuk kad pintar. (Untuk penjelasan terperinci tentang arti 100% murni, lihat bahagian Sumber.) OpenCard juga menyediakan pembangun dengan antara muka ke PC / SC (antara muka aplikasi kad pintar yang dikembangkan oleh Microsoft dan yang lain untuk berkomunikasi dengan kad pintar dari Win32 yang berasaskan platform untuk PC) untuk penggunaan peranti yang ada pada platform Win32. Baca terus dan pelajari cara menggunakan kad pintar dengan penyemak imbas anda.

Senibina OpenCard: Gambaran keseluruhan

OpenCard menyediakan arsitektur untuk mengembangkan aplikasi di Java yang menggunakan kad pintar atau peranti lain yang sesuai dengan ISO 7816 pada platform sasaran yang berbeza seperti Windows, komputer rangkaian, stesen kerja Unix, Webtops, set top, dan sebagainya. OpenCard Framework menyediakan antara muka pengaturcaraan aplikasi (API), yang membolehkan anda mendaftar kad, mencari kad di pembaca, dan secara opsional mempunyai ejen Java untuk memulakan apabila kad dimasukkan ke dalam pembaca. Senibina OpenCard digambarkan dalam Rajah 1.

Seni bina OpenCard Framework terdiri daripada CardTerminal, yang CardAgent, Ejen dan / atau aplikasi yang berinteraksi dengan komponen ini. OpenCard terdiri daripada empat pakej Java dengan awalan opencard :

  1. permohonan
  2. io
  3. ejen
  4. terminal

Pakej terminal dalam OpenCard

Pakej opencard.application dan opencard.io menyediakan API tahap tinggi yang digunakan oleh pembangun aplikasi. Perkhidmatan yang diperlukan oleh API peringkat tinggi dijalankan oleh kelas di opencard.agent dan opencard.terminal pakej. The opencard.agent pakej abstrak fungsi kad pintar melalui CardAgent. Pakej opencard.terminal mengaburkan terminal kad (juga dikenali sebagai pembaca kad ). Memahami struktur pakej opencard.terminal diperlukan untuk memahami contoh pelaksanaan terminal kad yang disediakan dalam artikel ini.

Terminal kad melengkapkan peranti yang digunakan dalam sistem komputer untuk berkomunikasi dengan kad pintar. The opencard.terminal pakej mengandungi kelas untuk mewakili perkakasan kad-terminal, untuk berinteraksi dengan pengguna, dan untuk menguruskan sumber kad-terminal. Tidak semua pembaca mempunyai kebolehan ini. Semasa melaksanakan pembaca yang tidak mempunyai entri papan kekunci, kami akan menggunakan UserInteractionHandler.

Perwakilan terminal kad

Setiap terminal kad diwakili oleh contoh kelas CardTerminalyang menentukan terminal kad yang mematuhi OpenCard abstrak. Terminal kad mungkin mempunyai satu atau lebih slot untuk kad pintar dan pilihan paparan dan papan kekunci atau pad PIN. Slot terminal kad ditunjukkan oleh contoh kelas abstrak Slot, yang menawarkan kaedah untuk menunggu kad dimasukkan, untuk berkomunikasi dengan kad, dan mengeluarkannya (jika mungkin).

Interaksi pengguna

Menggunakan kad pintar memerlukan interaksi dengan pengguna - untuk pengesahan pemegang kad. Antara muka UserInteractionmenyediakan fungsi ini. Ini menyediakan kaedah untuk menulis pesan ke layar dan menerima input dari pengguna. Terminal kad yang tidak menyokong semua ciri interaksi pengguna dapat memanfaatkannya UserInteractionHandler, yang mengimplementasikan a UserInteractionsebagai antara muka pengguna grafik berdasarkan toolkit abstrak (AWT).

Pengurusan sumber

Pembaca kad dan kad memerlukan pengurusan sumber sehingga ejen dapat diberikan tahap kawalan akses yang mereka perlukan. Pengurusan sumber menyediakan perkongsian terminal kad dan kad yang dimasukkan di dalamnya di antara ejen dalam sistem. Sebagai contoh, katakan anda menggunakan kad pintar anda untuk menandatangani dokumen pada masa yang sama dengan mesej e-mel keutamaan tinggi yang perlu disahkod menggunakan kad pintar anda. Pengurusan sumber menimbang aras akses ke CardTerminaldan port yang betul.

The resource management for card terminals is achieved by the CardTerminalRegistry class of OpenCard. There is only one instance of CardTerminalRegistry: the system-wide card terminal registry. The system-wide card terminal registry keeps track of the card terminals installed in the system. The card terminal registry can be configured from properties upon system start up or dynamically through register and unregister methods to dynamically add or remove card terminals from the registry.

During the registration of a card terminal, a CardTerminalFactory is needed to create an instance of the corresponding implementation class for the card terminal. The card terminal factory uses the type name and the connector type of the card terminal to determine the CardTerminal class to create. The concept of a card terminal factory allows a card terminal manufacturer to define a mapping between user-friendly type names and the class name.

Sample implementation: IBM card terminal

In this section, we'll describe the integration of the IBM 5948 card terminal into OpenCard. The IBM 5948 card terminal has one slot for smart cards, an LCD display, and a PIN pad. It is connected to the workstation or PC via a serial port. More information on this reader is available in the

Resources

section.

In order to access a card terminal from within OpenCard, an implementation for both abstract classes CardTerminal and Slot must be provided. These have been named IBM5948CardTerminal and IBM5948Slot, respectively. In addition, an appropriate CardTerminalFactory named IBMCardTerminalFactory is needed. The terminal implementation consists of package com.ibm.zurich.smartcard.terminal.ibm5948. Figure 2 depicts the inheritance relationships between the classes of opencard.terminal, the Java classes, and the terminal implementation. The class diagram also contains class IBM5948Driver, which does not implement any abstract class of OpenCard but serves as a Java interface to the terminal driver library written in 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

Terminal kad dikawal dengan menyerahkan PDU kawalan ke kaedah data dari IBM5948Driver. Format PDU kawalan mematuhi ISO 7816-4. Ini membolehkan kita menggunakan kelas opencard.agent.CommandPDUuntuk membina PDU dan opencard.agent.ResponsePDUmenangani tindak balas.

The IBM5948CardTerminalkelas memanjangkan kelas CardTerminal. Pembina memulakan kelas super dan memberi kesan kepada pemandu. Kemudian ia menetapkan susunan untuk menahan slot, dan memberi contoh satu contoh IBM5948Slotuntuk mewakili satu-satunya slot terminal kad IBM 5948.