Programování

Čipové karty a OpenCard Framework

Předchozí Java Developer Ve sloupci „Smart Card: A primer“ byl uveden obecný přehled čipových karet a jejich fungování. Zahrnoval část o standardech čipových karet, která představila koncept OpenCard. Jak je popsáno v prvním článku, OpenCard je otevřený standard, který poskytuje interoperabilitu aplikací čipových karet napříč NC, POS terminály, desktopy, notebooky, set topy a PDA. OpenCard může poskytovat 100% čisté aplikace Java smart card. Aplikace čipových karet často nejsou čisté, protože komunikují s externím zařízením nebo používají knihovny na klientovi. V tomto článku poskytneme dvě implementace dvěma různým čtečkám karet, což ukazuje, jak byste přidali podporu čteček karet na OpenCard. Doufáme, že porty pro Litronic, Gemplus, Schlumberger, Bull, Toshiba a SCM budou brzy k dispozici, komplimenty OpenCard a JavaWorld.

Úvod

Abyste mohli používat čipovou kartu, musíte být schopni kartu přečíst a komunikovat s ní pomocí aplikace. OpenCard poskytuje rámec pro toto tím, že definuje rozhraní, která musí být implementována. Rámec OpenCard definuje několik těchto rozhraní. Jakmile jsou tato rozhraní implementována, můžete v horních vrstvách API používat další služby. Například se čtečkou se správným rozhraním může OpenCard spustit agenta karet Java, kdykoli je karta vložena. Agent karty pak může komunikovat s aplikacemi na čipové kartě prostřednictvím terminálu karty v rámci relace.

Tento článek vás naučí, jak propojit terminály karet s OpenCard. Budoucí články pojednávají o tom, jak napsat agenta. K dispozici je malá testovací aplikace, která získá řetězec ATR (Answer to Reset). ATR je pro čipové karty zásadní. Vezmeme si vývojovou sadu OpenCard a vysvětlíme implementace pro dvě různé čtečky čipových karet pomocí rozhraní terminálu karty. Techniky popsané v článku pro zapnutí čteček, zahájení relací karet a použití datových jednotek protokolu a datových jednotek aplikačního protokolu lze znovu použít pro většinu čteček na trhu.

I když není nutné používat OpenCard při vytváření stoprocentně čistých aplikací Java smart card, vývojáři jsou bez ní nuceni používat k inteligentním kartám domácí rozhraní. (Podrobné vysvětlení toho, co ve skutečnosti znamená 100% čistota, najdete v části Zdroje.) OpenCard také poskytuje vývojářům rozhraní k PC / SC (aplikační rozhraní čipové karty vyvinuté společností Microsoft a dalšími pro komunikaci s čipovými kartami založenými na Win32) platformy pro PC) pro použití stávajících zařízení na platformách Win32. Čtěte dále a dozvíte se, jak používat čipové karty v prohlížeči.

Architektura OpenCard: Přehled

OpenCard poskytuje architekturu pro vývoj aplikací v Javě, které využívají čipové karty nebo jiná zařízení kompatibilní s normou ISO 7816 na různých cílových platformách, jako jsou Windows, síťové počítače, pracovní stanice Unix, Webtops, set tops atd. OpenCard Framework poskytuje rozhraní pro programování aplikací (API), které vám umožňuje registrovat karty, hledat karty ve čtečkách a volitelně spouštět agenty Java po vložení karet do čtečky. Architektura OpenCard je znázorněna na obrázku 1.

Architektura OpenCard Framework je tvořena CardTerminalCardAgent, zástupci a / nebo aplikace, které interagují s těmito komponentami. OpenCard se skládá ze čtyř balíčků Java s předponou otevřená karta:

  1. aplikace
  2. io
  3. činidlo
  4. terminál

Balíček terminálu v OpenCard

Balíčky opencard. aplikace a opencard.io poskytnout rozhraní API na vysoké úrovni používané vývojářem aplikace. Služby potřebné pro rozhraní API na vysoké úrovni jsou prováděny třídami v opencard.agent a otevřená karta. terminál balíčky. The opencard.agent balíček abstrahuje funkčnost čipové karty prostřednictvím CardAgent. Balík otevřená karta. terminál abstrahuje terminály karet (také známé jako čtečky karet). Pochopení struktury otevřená karta. terminál balíček je nutný k pochopení ukázkových implementací karetních terminálů uvedených v tomto článku.

Terminál karty odebírá zařízení, které se používá v počítačovém systému ke komunikaci s čipovou kartou. The otevřená karta. terminál balíček obsahuje třídy představující hardware terminálu karty, interakci s uživatelem a správu zdrojů terminálu karty. Ne všichni čtenáři mají tyto schopnosti. Při implementaci čtečky, která nemá vstup z klávesnice, použijeme UserInteractionHandler.

Reprezentace terminálu karty

Každý terminál karty je reprezentován instancí třídy CardTerminal který definuje abstraktní terminál karty kompatibilní s OpenCard. Terminál karty může mít jeden nebo více slotů pro čipové karty a volitelně displej a klávesnici nebo PIN. Sloty terminálu karty jsou reprezentovány instancemi abstraktní třídy Slot, který nabízí způsoby čekání na vložení karty, komunikace s kartou a jejího vysunutí (je-li to možné).

Interakce uživatele

Použití čipové karty vyžaduje interakci s uživatelem - pro ověření držitele karty. Rozhraní Interakce uživatele poskytuje tuto funkci. Poskytuje metody pro psaní zpráv na displej a přijímání vstupů od uživatele. Kartové terminály, které nepodporují všechny funkce interakce s uživatelem, mohou využívat UserInteractionHandler, který implementuje a Interakce uživatele jako grafické uživatelské rozhraní založené na sadě abstraktních oken (AWT).

Správa zdrojů

Karty a čtečky karet vyžadují správu prostředků, aby agentům mohla být udělena požadovaná úroveň kontroly přístupu. Správa zdrojů umožňuje sdílení terminálů karet a karet v nich vložených mezi agenty v systému. Řekněme například, že používáte svou čipovou kartu k podepisování dokumentu ve stejnou dobu, kdy přichází poštovní zpráva s vysokou prioritou, kterou je třeba pomocí čipové karty dekódovat. Správa zdrojů rozhoduje o přístupu k CardTerminal a správný port.

Řízení zdrojů pro terminály karet je dosaženo pomocí CardTerminalRegistrace třída OpenCard. Existuje pouze jedna instance CardTerminalRegistrace: registr terminálu karet celého systému. Registr terminálů karet v celém systému sleduje terminály karet nainstalované v systému. Registr terminálu karty lze konfigurovat z vlastností při spuštění systému nebo dynamicky prostřednictvím Registrovat a zrušit registraci metody dynamického přidávání nebo odebírání terminálů karet z registru.

Při registraci kartového terminálu a CardTerminalFactory je potřeba k vytvoření instance odpovídající implementační třídy pro terminál karty. Továrna terminálu karty používá k určení názvu typu a typu konektoru terminálu karty CardTerminal třída k vytvoření. Koncept továrny na karetní terminály umožňuje výrobci karetních terminálů definovat mapování mezi uživatelsky přívětivými názvy typů a názvy tříd.

Ukázková implementace: IBM card terminal

V této části si popíšeme integraci terminálu karty IBM 5948 do OpenCard. Terminál karet IBM 5948 má jeden slot pro čipové karty, LCD displej a PIN. Je připojen k pracovní stanici nebo PC přes sériový port. Více informací o této čtečce je k dispozici na webu

Zdroje

sekce.

Aby bylo možné přistupovat ke kartovému terminálu z OpenCard, implementace pro obě abstraktní třídy CardTerminal a Slot musí být poskytnuto. Tito byli jmenováni Terminál IBM5948Card a IBM5948Slot, resp. Kromě toho vhodné CardTerminalFactory pojmenovaný IBMCardTerminalFactory je potřeba. Implementace terminálu se skládá z balíčku com.ibm.zurich.smartcard.terminál.ibm5948. Obrázek 2 zobrazuje vztahy dědičnosti mezi třídami otevřená karta. terminál, třídy Java a implementace terminálu. Diagram tříd také obsahuje třídu Ovladač IBM5948, který neimplementuje žádnou abstraktní třídu OpenCard, ale slouží jako rozhraní Java pro knihovnu ovladačů terminálu napsanou v C.

Předpokládáme, že terminál je již připojen k pracovní stanici nebo počítači a že sériový port je nakonfigurován pro práci s terminálem. V následující části popisujeme návrh a implementaci ovladače, terminálu, slotu a továrny na terminálové karty. K dispozici je také konfigurace registru terminálu karty.

Ovladač terminálu karty

Terminál karty je dodáván s ovladačem, který je k dispozici jako knihovna dynamických odkazů (DLL). DLL má C API, které nabízí funkce CT_init, CT_data, a CT_close:

  • Funkce CT_init se používá k otevření připojení ke svorce karty, která je připojena k určitému sériovému portu. Po navázání spojení lze vyměnit datové jednotky protokolu (PDU) s terminálem karty a APU lze vyměnit pomocí čipové karty, která je zasunuta do slotu terminálu přes CT_data funkce.

  • The CT_data volání se používá k odeslání jedné PDU a získání odpovědi z terminálu nebo čipové karty.

  • The CT_close funkce slouží k ukončení spojení s terminálem karty a uvolnění veškerých prostředků.

Úspěch nebo neúspěch všech tří volání API je indikován návratovým kódem.

Rozhraní Java API

Podobně jako u C API definujeme Java API pro ovladač terminálu karty. Rozhraní Java API pro terminál karty se skládá z třídy Ovladač IBM5948, který má nativní metody volání C API. Rozhodli jsme se implementovat co nejvíce funkcí v Javě a mít v C. napsán pouze nějaký „lepicí“ kód. Ve skutečnosti byly parametry ctInit a ctClose metoda je právě předána příslušné funkci C API. Vzhledem k tomu, že pole jsou v C a Javě uspořádána odlišně, je třeba je zpracovat voláním rozhraní API virtuálního počítače Java Native Interface (JNI). Nativní metody vracejí návratový kód rozhraní C API. Provádění ctData metoda je uvedena níže:

JNIEXPORT jint JNICALL Java_com_ibm_zurich_smartcard_terminal_ibm5948_IBM5948Driver_ctData (JNIEnv * env, jobject that, jbyte destination, jbyteArray příkaz, jint commandLength, jbyteArray odpověď, jint responseMax) {short rc; unsigned char sad = HOST; unsigned char dad = cíl; unsigned short responseLength = (unsigned short) responseMax; unsigned char * commandArray; nepodepsaný char * responseArray; jclass cls = (* env) -> GetObjectClass (env, to); jfieldID fid; jint ctn; fid = (* env) -> GetFieldID (env, cls, "ctNumber", "I"); if (fid == NULL) {návrat (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) {návrat (CT_ERR_HTSI); } (* env) -> SetIntField (env, that, fid, responseLength); návrat rc; } 

Nativní metody popsané výše napodobují C API v Javě. Důvodem bylo mít co nejméně kódu C, který by bylo možné udržovat. Kromě nativních metod, které jsou soukromé, metody inic, data, a zavřít jsou implementovány. Volají nativní metody a vyvolávají výjimku, pokud návratový kód označuje chybu. V případě datové metody se bajtové pole odpovědi vrátí po úspěšném dokončení volání nativní metody. Níže uvedený příklad ukazuje datovou metodu:

synchronizovaná data bajtu [] (cíl bajtu, byte [] pdu) vyvolá výjimku CardTerminalException {int rc = ctData (cíl, pdu, pdu.length, response, response.length); if (rc == CT_OK) {byte [] result = new byte [responseLength]; System.arraycopy (response, 0, result, 0, responseLength); vrátit výsledek; } else throw new CardTerminalException (rc2String (rc)); } 

Aby se správa paměti udržovala v prostředí Java, je odpověď na vyrovnávací paměť pro odpověď z terminálu přidělena jednou a předána nativnímu kódu. Vzhledem k tomu, že C API není znovu vstupující, metody Ovladač IBM5948 musí být prohlášena za synchronizovanou.

Implementace terminálu karty

Kartový terminál je řízen odesláním řídících PDU datové metodě Ovladač IBM5948. Formát řídicích jednotek PDU je v souladu s normou ISO 7816-4. To nám umožňuje nasadit třídu opencard.agent.CommandPDU postavit PDU a opencard.agent.ResponsePDU zpracovat odpovědi.

The Terminál IBM5948Card třída rozšiřuje třídu CardTerminal. Konstruktor inicializuje super třídu a vytvoří instanci ovladače. Pak vytvoří instanci pole, aby drželo sloty, a vytvoří instanci jedné instance IBM5948Slot představuje jediný slot terminálu karty IBM 5948.