Programmering

Smartkort og OpenCard Framework

Den forrige Java Developer kolonne, "Smart cards: A primer", ga en generell oversikt over smartkort og hvordan de fungerer. Den inkluderte en seksjon om smartkortstandarder som introduserte konseptet med OpenCard. Som beskrevet i den første artikkelen er OpenCard en åpen standard som gir interoperabilitet for smartkortapplikasjoner på tvers av NC-er, POS-terminaler, stasjonære datamaskiner, bærbare datamaskiner, set-tops og PDA-er. OpenCard kan tilby 100% rene Java-smartkortapplikasjoner. Smartkortapplikasjoner er ofte ikke rene fordi de kommuniserer med en ekstern enhet eller bruker biblioteker på klienten. I denne artikkelen vil vi gi to implementeringer til to forskjellige kortlesere, som viser hvordan du vil legge til støtte for kortlesere til OpenCard. Vi håper at porter for Litronic, Gemplus, Schlumberger, Bull, Toshiba og SCM snart vil være tilgjengelige, komplimenter av OpenCard og JavaWorld.

Introduksjon

For å kunne bruke et smartkort, må du kunne lese kortet og kommunisere med det ved hjelp av et program. OpenCard gir et rammeverk for dette ved å definere grensesnitt som må implementeres. OpenCard-rammeverket definerer flere av disse grensesnittene. Når disse grensesnittene er implementert, kan du bruke andre tjenester i de øvre lagene i APIen. For eksempel, med en korrekt grensesnittleser, kan OpenCard starte en Java-kortagent når kortet settes inn. Kortagenten kan da kommunisere med applikasjoner på smartkortet via kortterminalen i sammenheng med en økt.

Denne artikkelen vil lære deg hvordan du kobler kortterminaler til OpenCard. Fremtidige artikler vil diskutere hvordan man skriver en agent. En liten testapplikasjon som får ATR (Answer to Reset) -strengen er gitt. ATR er grunnleggende for smartkort. Vi tar OpenCard-utviklingssettet og forklarer implementeringer for to forskjellige smartkortlesere ved hjelp av Card Terminal Interface. Teknikkene diskutert i artikkelen for å slå på lesere, starte kortøkter og bruk av Protocol Data Units og Application Protocol Data Units kan brukes på nytt for de fleste lesere på markedet.

Selv om det ikke er nødvendig å bruke OpenCard til å lage 100% rene Java-smartkortapplikasjoner, uten at utviklere blir tvunget til å bruke hjemmelagde grensesnitt til smartkort. (For en detaljert forklaring på hva 100% rent egentlig betyr, se Ressurser-delen.) OpenCard gir også utviklere et grensesnitt til PC / SC (et smartkortapplikasjonsgrensesnitt utviklet av Microsoft og andre for å kommunisere med smartkort fra Win32-baserte. plattformer for PC-er) for bruk av eksisterende enheter på Win32-plattformer. Les videre og lær hvordan du bruker smartkort med nettleseren din.

OpenCard-arkitektur: En oversikt

OpenCard gir en arkitektur for å utvikle applikasjoner i Java som bruker smartkort eller andre ISO 7816-kompatible enheter på forskjellige målplattformer som Windows, nettverksdatamaskiner, Unix arbeidsstasjoner, Webtops, set tops og så videre. OpenCard Framework tilbyr et applikasjonsprogrammeringsgrensesnitt (API), som lar deg registrere kort, se etter kort i leserne, og eventuelt få Java-agenter til å starte når kort settes inn i leseren. Arkitekturen til OpenCard er avbildet i figur 1.

Arkitekturen til OpenCard Framework består av CardTerminal, den CardAgent, agentene og / eller applikasjonene som samhandler med disse komponentene. OpenCard består av fire Java-pakker med prefikset åpent kort:

  1. applikasjon
  2. io
  3. middel
  4. terminal

Terminalpakken i OpenCard

Pakker opencard.application og opencard.io gi API på høyt nivå som brukes av programutvikleren. Tjenestene som trengs av API-et på høyt nivå, utføres av klasser i opencard.agent og åpent kort. terminal pakker. De opencard.agent pakken trekker ut funksjonaliteten til smartkortet gjennom CardAgent. Pakke åpent kort. terminal trekker ut kortterminalene (også kjent som kortlesere). Forstå strukturen til åpent kort. terminal pakken er nødvendig for å forstå eksemplet på implementeringer av kortterminaler gitt i denne artikkelen.

En kortterminal trekker ut enheten som brukes i et datasystem for å kommunisere med et smartkort. De opencard.terminal pakken inneholder klasser for å representere kortterminalens maskinvare, for å samhandle med brukeren og for å administrere kortterminalressurser. Ikke alle lesere har disse evnene. Når vi implementerer en leser som ikke har tastaturinngang, bruker vi UserInteractionHandler.

Kortterminalrepresentasjon

Hver kortterminal er representert av en forekomst av klasse CardTerminal som definerer den abstrakte OpenCard-kompatible kortterminalen. En kortterminal kan ha ett eller flere spor for smartkort og eventuelt en skjerm og et tastatur eller PIN-tastatur. Sporene til en kortterminal er representert av forekomster av den abstrakte klassen Slot, som tilbyr metoder for å vente på at et kort skal settes inn, for å kommunisere med kortet og for å løse det ut (hvis mulig).

Brukerinteraksjon

Å bruke et smartkort krever samhandling med brukeren - for bekreftelse av kortholderen. Grensesnittet Brukerinteraksjon sørger for denne funksjonaliteten. Det gir metoder for å skrive en melding på skjermen og motta innspill fra brukeren. Kortterminaler som ikke støtter alle funksjoner for brukerinteraksjon, kan bruke UserInteractionHandler, som implementerer en Brukerinteraksjon som et grafisk brukergrensesnitt basert på det abstrakte vindusverktøyet (AWT).

Ressursforvaltning

Kort og kortlesere krever ressursadministrasjon slik at agenter kan få tilgangskontrollnivået de trenger. Ressursadministrasjon sørger for deling av kortterminaler og kortene som er satt inn i dem mellom agentene i systemet. Si for eksempel at du bruker smartkortet ditt til å signere et dokument samtidig som det kommer en e-postmelding med høy prioritet som må dekodes ved hjelp av smartkortet. Ressursadministrasjon arbitrer tilgangen til CardTerminal og riktig port.

Ressursadministrasjonen for kortterminaler oppnås av CardTerminalRegistry klasse av OpenCard. Det er bare en forekomst av CardTerminalRegistry: det systemomfattende kortterminalregistret. Det systemomfattende kortterminalregistret holder oversikt over kortterminalene som er installert i systemet. Kortterminalregistret kan konfigureres fra egenskaper ved systemstart eller dynamisk gjennom registrere og avregistrere metoder for dynamisk å legge til eller fjerne kortterminaler fra registeret.

Under registreringen av en kortterminal, a CardTerminalFactory er nødvendig for å opprette en forekomst av den tilsvarende implementeringsklassen for kortterminalen. Kortterminalfabrikken bruker typenavnet og kontakttypen til kortterminalen for å bestemme CardTerminal klasse å lage. Konseptet med en kortterminalfabrikk lar en kortterminalprodusent definere en kartlegging mellom brukervennlige typenavn og klassenavnet.

Eksempel på implementering: IBM-kortterminal

I denne delen vil vi beskrive integrasjonen av IBM 5948-kortterminalen i OpenCard. IBM 5948-kortterminalen har ett spor for smartkort, en LCD-skjerm og en PIN-plate. Den er koblet til arbeidsstasjonen eller PC-en via en seriell port. Mer informasjon om denne leseren er tilgjengelig i

Ressurser

seksjon.

For å få tilgang til en kortterminal fra OpenCard, en implementering for begge abstrakte klasser CardTerminal og Slot må leveres. Disse har fått navn IBM5948CardTerminal og IBM5948Slot, henholdsvis. I tillegg en passende CardTerminalFactory heter IBMCardTerminalFactory trengs. Terminalimplementeringen består av pakke com.ibm.zurich.smartcard.terminal.ibm5948. Figur 2 viser arveforholdet mellom klassene i åpent kort. terminal, Java-klassene og terminalimplementeringen. Klassediagrammet inneholder også klasse IBM5948Driver, som ikke implementerer noen abstrakt klasse av OpenCard, men fungerer som et Java-grensesnitt til terminaldriverbiblioteket skrevet i C.

Vi antar at terminalen allerede er koblet til arbeidsstasjonen eller PCen, og at den serielle porten er konfigurert til å fungere med terminalen. I det følgende avsnittet beskriver vi utformingen og implementeringen av driveren, terminalen, sporet og kortterminalfabrikken. Konfigurasjonen av kortterminalregisteret er også gitt.

Kortterminalføreren

Kortterminalen leveres med en driver som er tilgjengelig som et dynamisk lenkebibliotek (DLL). DLL har et C API som tilbyr funksjonene CT_init, CT_data, og CT_lukk:

  • Funksjonen CT_init brukes til å åpne en forbindelse til en kortterminal som er koblet til en bestemt seriell port. Etter at forbindelsen er opprettet, kan protokolldataenheter (PDU) byttes ut med kortterminalen, og APU-er kan byttes ut med smartkortet som er koblet til sporet på terminalen via CT_data funksjon.

  • De CT_data samtale brukes til å sende en PDU og hente svaret fra henholdsvis terminalen eller smartkortet.

  • De CT_lukk funksjonen brukes til å lukke forbindelsen til kortterminalen og frigjøre eventuelle ressurser.

Suksess eller feil på alle de tre API-anropene er angitt med returkoden.

Java API

I likhet med C API, definerer vi en Java API for kortterminaldriveren. Java API for kortterminalen består av klasse IBM5948Driver, som har innfødte metoder som kaller C API. Vi bestemte oss for å implementere så mye funksjonalitet som mulig i Java og har bare noen "lim" -koder skrevet i C. Faktisk er parametrene til ctInit og ctLukk metoden blir nettopp videreført til den respektive C API-funksjonen. Siden matriser er organisert annerledes i C og Java, må de håndteres av samtaler til Java Native Interface (JNI) API på den virtuelle maskinen. De opprinnelige metodene returnerer returkoden til C API. Gjennomføringen av ctData metoden er vist nedenfor:

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; usignert røye trist = VERT; usignert char pappa = destinasjon; usignert kort responsLength = (usignert kort) responseMax; usignert char * commandArray; usignert røye * responsArray; jclass cls = (* env) -> GetObjectClass (env, that); jfieldID fid; jint ctn; fid = (* env) -> GetFieldID (env, cls, "ctNumber", "I"); hvis (fid == NULL) {retur (CT_ERR_HTSI); } ctn = (* env) -> GetIntField (env, that, fid); commandArray = (usignert tegn *) (* env) -> GetByteArrayElements (env, kommando, 0); responseArray = (usignert røye *) (* env) -> GetByteArrayElements (env, respons, 0); rc = CT_DATA (ctn, & dad, & sad, commandLength, commandArray, & responseLength, responseArray); (* env) -> ReleaseByteArrayElements (env, command, (signert char *) commandArray, 0); (* env) -> ReleaseByteArrayElements (env, respons, (signert char *) responseArray, 0); fid = (* env) -> GetFieldID (env, cls, "responseLength", "I"); hvis (fid == NULL) {retur (CT_ERR_HTSI); } (* env) -> SetIntField (env, that, fid, responseLength); retur rc; } 

De opprinnelige metodene som er beskrevet ovenfor, etterligner C API i Java. Årsaken til dette var å ha så lite C-kode å vedlikeholde som mulig. På toppen av de innfødte metodene, som er private, metodene i det, data, og Lukk blir implementert. De kaller de innfødte metodene og kaster et unntak hvis returkoden indikerer en feil. I tilfelle av datametoden returneres responsbyte-matrisen etter vellykket gjennomføring av den opprinnelige metodeanropet. Eksemplet nedenfor viser datametoden:

synkronisert byte [] data (byte destinasjon, byte [] pdu) kaster CardTerminalException {int rc = ctData (destinasjon, pdu, pdu.length, respons, respons.length); hvis (rc == CT_OK) {byte [] resultat = ny byte [responsLengde]; System.arraycopy (respons, 0, resultat, 0, responsLength); returresultat; } ellers kaste nytt CardTerminalException (rc2String (rc)); } 

For å holde minnestyring inne i Java, tildeles en buffersvar for svaret fra terminalen en gang og sendes videre til den opprinnelige koden. Siden C API ikke er med på nytt, er metodene for IBM5948Driver må erklæres synkronisert.

Implementering av kortterminalen

Kortterminalen styres ved å sende kontroll-PDUer til datametoden til IBM5948Driver. Kontroll-PDU-ene har formatet ISO 7816-4. Dette lar oss distribuere klassen opencard.agent.CommandPDU å konstruere PDU-ene og opencard.agent.ResponsePDU for å håndtere svarene.

De IBM5948CardTerminal klasse utvider klassen CardTerminal. Konstruktøren initialiserer superklassen og instanserer sjåføren. Deretter instantierer det matrisen for å holde sporene, og instantierer en forekomst av IBM5948Slot å representere det eneste sporet til IBM 5948-kortterminalen.

$config[zx-auto] not found$config[zx-overlay] not found