Karty inteligentne
Wprowadzenie Karty tłoczone Karty magnetyczne Karty elektroniczne (inteligentne, smart card) Pamięciowe, mikroprocesorowe Stykowe, bezstykowe (contactless), hybrydowe
Historia 1968 (Jürgen Dethloff i Helmut Grötrupp, Niemcy) idea karty opartej na układzie elektronicznym, 1970 (Kunitaka Arimura, Japonia) 1974 (Roland Moreno, Francja) zastosowanie karty w systemie płatniczym 1979 pierwsza karta procesorowa 1995 szerokie wykorzystanie kart procesorowych
Obszary zastosowań Transakcje płatnicze Programy lojalnościowe Zapis danych biometrycznych (elektroniczny dowód osobisty) Infrastruktura klucza publicznego (podpis cyfrowy) System GSM
Budowa karty
Rodzaje kart inteligentnych Natywne COS (Card OS) EMV (EN1546) JavaCard (ISO 7816) MPCOS, Cryptoflex, GemClub 3GPP, GSM (GSM 11.11) small OS.NET smartcard
Polecenia systemu operacyjnego READ BINARY odczyt pliku, WRITE BINARY zapis do pliku, UPDATE BINARY modyfikacja pliku, ERASE BINARY czyszczenie pliku, READ RECORD odczyt rekordu, WRITE RECORD zapis rekordu, APPEND RECORD dodanie rekordu, UPDATE RECORD modyfikacja rekordu, GET DATA odczyt danych z pliku, PUT DATA zapis danych do pliku, SELECT FILE wybór pliku, VERIFY weryfikacja np. hasła, INTERNAL AUTHENTICATE uwierzytelnienie karty, EXTERNAL AUTHENTICATE uwierzytelnienie terminala, GET CHALLENGE generacja liczby pseudolosowej, MANAGE CHANNEL zarządzanie kanałami logicznymi, GET RESPONSE pobranie odpowiedzi od karty związanej z ostatnio wydanym poleceniem, ENVELOPE umożliwia np. przesyłanie danych, które będą interpretowane jako komenda
Architektura aplikacji z SC Aplikacja kliencka Aplikacja karty Interfejs współpracy z czytnikiem CT-API PC/SC OCF SATSA API SO Czytnik
Czytniki i terminale Czytniki transmisja szeregowa z terminalem (np. PC) Pasywne Aktywne Firmy Phoenix GemPlus
Komunikacja system-karta System zewnętrzny ATR APDU Smart Cart Transmisja szeregowa asynchroniczna Synchroniczna Protokoły T0 T15 norma ISO 7816-3 RAPDU APDU
ATR i APDU TS T0 TA1 TB1... T1 T2... TCK CLA INS P1 P2 Lc Data Le CLA 0x rozkazy zgodne z ISO 7816 80 elektroniczna portmonetka 8x rozkazy specyficzne dla aplikacji A0 aplikacja GSM
RAPDU Data Sw1 Sw2 Status (sw1) 61, 90- OK. 62, 63 rozkaz zakończony ostrzeżeniem 64, 65 błąd wykonania rozkazu 67, 6F błąd sprawdzenia rozkazu
Architektura JavaCard instancja 1 apletu instancja 1 apletu aplety (cardlets) dodatkowe API JavaCard API JavaCard VM System operacyjny
Ograniczenia JCVM brak typów danych: long, double, float, char, brak klasy java.lang.system (została zastąpiona przez javacard.framework.jcsystem), brak procesu garbage collection (ponadto w rzeczywistych kartach nie ma możliwości defragmentacji użytej pamięci), brak Security Manager, nie ma możliwości stosowania wątków, dynamicznego ładowania klas, klonowania obiektów oraz używania wielowymiarowych struktur danych,
JCDK java.sun.com/javacard JavaCard Development Kit (JCDK) J2SE OpenCard Framework (dla aplikacji klienckich)
JavaCard API java.lang zawiera podzbiór podstawowych klas języka Java przeznaczonych dla kart, java.io podzbiór tego pakietu związany z wyjątkami, java.rmi pakiet używany do definiowania zdalnego interfejsu karty czyli metod wywoływanych przez CAD (chip accepting device); pozwala to na tworzenie aplikacji terminalowej w architekturze RMI, javacard.framework dostarcza strukturę klas i interfejsów używanych przy tworzeniu i komunikowaniu się z apletami kartowymi, javacard.security zestaw klas i interfejsów związanych z bezpieczeństwem, javacardx.crypto zestaw dodatkowych funkcji kryptograficznych. javacard.framework.applet jest to abstrakcyjna klasa bazowa dla wszystkich apletów, javacard.framework.aid używana jest do przechowywania AID (application identifier) aplikacji; JCRE tworzy instancję tej klasy w celu zarządzania i identyfikacji apletu, javacard.framework.apdu wykorzystywana do przechowywania rozkazu albo odpowiedzi APDU; klasa zaprojektowana jest do obsługi APDU niezależnie od stosowanego protokołu, javacard.framework.util klasa zawiera zestaw przydatnych statycznych metod (kopiowanie i porównywanie tablic, konkatenacja i rozdzielanie bajtów), javacard.framework.ownerpin klasa przeznaczona do przechowywania i zarządzania kodem PIN właściciela karty javacard.framework.iso7816 zawiera zestaw predefiniowanych stałych javacard.security.key bazowy interfejs dla wszystkich klas reprezentujących klucze,
Architektura kardletu import javacard.framework.*; public class Purse extends Applet { protected Purse () { } public static void install(byte[] barray, short boffset, byte blength) throws ISOException { Purse applet = new Purse(); } public void process(apdu apdu) throws ISOException { byte buffer[] = apdu.getbuffer(); } } public void select() { } public void deselect() { }
Projekt Operacja CLA INS Parametry dane Odpowiedź CREDIT 0x80 0x50 - Kwota (2 bajty) Aktualne saldo (2 bajty) lub kod błędu BALANCE 0x80 0x52 - Aktualne saldo i status DEBIT 0x80 0x54 - Kwota (2 bajty) Aktualne saldo (2 bajty) lub kod błędu VER_PIN 0x80 0x56 P1 P2 0x01 (kod użytk) - 0x02 (kod właśc) Kod PIN Status (sw2 ilośc pozostałych prób) UPD_PIN 0x80 0x58 P1 P2 0x01 (kod użytk) - 0x02 (kod właśc) Kod PIN Status
Implementacja package frst; import javacard.framework.*; public class Purse extends Applet { private final static byte PURSE_CLA = (byte)0x80; private final static byte CREDIT_INS = (byte)0x50; private final static byte BALANCE_INS = (byte)0x52; private final static byte DEBIT_INS = (byte)0x54; private final static byte VERIFY_PIN_INS = (byte)0x56; private final static byte UPDATE_PIN_INS = (byte)0x58; private final static short SW_DEBIT_VALUE_TOO_HIGH = (short)0x9101; private final static short SW_CREDIT_VALUE_TOO_HIGH = (short)0x9102; private final static short SW_WRONG_PIN = (short)0x69c0; private OwnerPIN userpin; private final static byte USER_PIN_P2 = (byte)0x01; private OwnerPIN ownerpin; private final static byte OWNER_PIN_P2 = (byte)0x02; private short balance; private static final short maximumbalance = (short)30000;
Implementacja public static void install(byte[] barray, short boffset, byte blength) throws ISOException { // dlugosc AID byte aidlen = barray[boffset]; short aidoffset=(short)(boffset+1); boffset = (short)(boffset+aidlen+1); // dlugosc danych kontrolnych byte clen=barray[boffset]; boffset=(short)(boffset+clen+1); // dlugosc danych dla apletu byte alen=barray[boffset]; } // stworzenie instancji apletu Purse applet = new Purse(bArray, (short)(boffset+(short)2), barray[(short)(boffset+(short)1)], (short)(boffset+(short)3+(short)barray[(short)(boffset+(short)1)]), barray[(short)(boffset+(short)2+(short)barray[(short)(boffset+(short)1)])]);... return;
public void deselect() { ownerpin.reset(); userpin.reset(); } Implementacja
Implementacja public void process(apdu apdu) throws ISOException { byte buffer[] = apdu.getbuffer(); } else if (buffer[iso7816.offset_cla] == ISO7816.CLA_ISO7816) { if (buffer[iso7816.offset_ins] == ISO7816.INS_SELECT) { if (selectingapplet()) { apdu.setoutgoingandsend((short)0, (short)0);} else { ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } } } if (buffer[iso7816.offset_cla] == PURSE_CLA) { switch (buffer[iso7816.offset_ins]) { case CREDIT_INS : processcredit(apdu); break; case BALANCE_INS : {...} case DEBIT_INS : {...} case VERIFY_PIN_INS : {...} case UPDATE_PIN_INS : {...} default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); break; } } else { ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);}
Implementacja [PURSE_CLA] [CREDIT_INS] 0x00 0x00 0x02 [CREDIT_VAL_1] [CREDIT_VAL_2] 0x02 0x80 0x50 0x00 0x00 0x02 0x00 0x01 0x02 private void processcredit(apdu apdu) { if (!ownerpin.isvalidated()) ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED); // odebranie danych przeslanych w komendzie APDU byte[] buffer = apdu.getbuffer(); byte datalength = buffer[iso7816.offset_lc]; //0x02 if (datalength!=2 datalength!=apdu.setincomingandreceive()) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);} short amount = (short)(((buffer[iso7816.offset_cdata+1] ) & (short)0x00ff) ((buffer[iso7816.offset_cdata] << 8) & (short)0xff00)); } if (((short)(balance + amount) > maximumbalance) (amount <= (short)0)) ISOException.throwIt(SW_CREDIT_VALUE_TOO_HIGH); else { balance += amount;} buffer[0] = (byte)(balance >> 8); buffer[1] = (byte)balance; apdu.setoutgoing(); apdu.setoutgoinglength((short)2); apdu.sendbytes((short)0, (short)2);
Kompilacja Przykład App/kardlet.java javac g classpath <> -target 1.1 App/kardlet.java kardlet.class
Konwersja out EXP JCA CAP exportpath. applet 0xa0:0x0:0x0:0x0:0x62:0x0:0x0:0x0:0x2:0x1 App.kardlet App 0xa0:0x0:0x0:0x0:0x62:0x0:0x0:0x0:0x2 1.0 converter config plik.opt weryfikacja
Emulacja App 0xa0:0x0:0x0:0x0:0x62:0x0:0x0:0x0:0x2 com.sun.javacard.samples.wallet.wallet \ 0xa0:0x0:0x0:0x0:0x62:0x3:0x1:0xc:0x6:0x1 JCDWE cref
Architektura aplikacji z SC Aplikacja kliencka Aplikacja karty Interfejs współpracy z czytnikiem CT-API PC/SC OCF SATSA API SO Czytnik
OpenCard Framework W odróżnieniu od innych API, podstawowym celem OCF było uniezależnienie się od Producentów czytników kart (CardTerminal) SO karty (CardService) Dostawców aplikacji kartowych (ApplicationManagementCardService)
Architektura aplikacji z OFC
Konfiguracja opencard.properties #wysylanie APDU OpenCard.services = opencard.opt.util.passthrucardservicefactory # wirtualny terminal cref OpenCard.terminals=com.ibm.opencard.terminal.ibm5948.IBMCardTerminalFactory cref CREF localhost:9025 #com.isun.javacard.crefterminal.crefcardterminalfactory cref CREF localhost :9025 # sledzenie przebiegu aplikacji OpenCard.trace = opencard:3 com.sun:3 OpenCard.services.override = true OpenCard.terminals.override = true OpenCard.trace.override = true
Aplikacja OCF // uruchomienie uslugi SmartCard.start(); // oczekiwanie na karte CardRequest cr = new CardRequest(); cr.setwaitbehavior(cardrequest.anycard); SmartCard sc = SmartCard.waitForCard(cr); // identyfikator karty System.out.println(sc.getCardID()); ptcs=(passthrucardservice)sc.getcardservice(passthrucardservice.class, true); // wybranie apletu elektronicznej portmonetki final byte[] SELECT_PURSE={ (byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x0a,(byte)0xd2, (byte)0x76, (byte)0x00, (byte)0x01, (byte)0x25, (byte)0x00, (byte)0x01,(byte)0x00, (byte)0x05, (byte)0x01, (byte)0x00}; // przeslanie komendy CommandAPDU apdu = new CommandAPDU(SELECT_PURSE); ResponseAPDU rapdu = ptcs.sendcommandapdu(apdu); if (rapdu.sw1()!=(byte)0x90) throw new Exception("Brak apletu PURSE w karcie!");
Karty.NET Dla systemów przed Vistą należy zainstalować uaktualnienie CSP (Cmar Card Crypotgraphic Service Provider) Do zarządzania certyfikatami używa się Certificate Lifecycle Manager.
Cykl życia karty implementacja proces w którym tworzona jest aplikacji zgodna z.net np. w języku C# lub VisualBasic.NET. Po tym jak aplikacja jest zapisana przeprowadzany jest proces kompilacji do kodu pośredniego CIL / MSIL. W normalnym środowisku aplikacja w postaci skompilowanego kodu CIL jest tłumaczona na kod maszynowy poprzez maszynę wirtualną CLR. W przypadku karty elektronicznej przed załadowaniem aplikacji na kartę, kod aplikacji tłumaczony jest na.net Smart Card Framework card-resident format binarny, który wielokrotnie pomniejsza rozmiar końcowego pliku. Każdy plik w postaci binarnej ładowany na kartę musi być podpisany elektronicznie tak aby można było zweryfikować jego pochodzenia / autora.
instalacja po załadowaniu pliku binarnego na pamięć karty, wywoływana jest główna metoda aplikacji: public static int Main. Powoduje to rozpoczęcie instalacji tj. zarejestrowania zdalnych typów, aby umożliwić klientom zdalne wywoływanie metod aplikacji znajdujących się na karcie elektronicznej
wykonywanie aplikacji Framework elektronicznej karty.net cechuje model relacji typu klient serwer. Za serwer przyjmuje się kartę elektroniczną, na której aplikacje są uruchamiane zdalnie poprzez terminal (klienta). Stan wykonania aplikacji na karcie jest ciągle utrwalany co w przypadku awarii zasilania lub wysunięcia w nieodpowiednim momencie karty pozwala na przywrócenie stanu aplikacji z przed zdarzenia
terminacja aplikacji (zakończenie jej działania) aplikacja działająca na serwerze (karcie elektronicznej), przestaje działać w momencie jej wyrejestrowania. Można to uczynić programowo lub poprzez narzędzie Card Explorer. Po wyrejestrowaniu usługi (aplikacji) instancja aplikacji zostanie usunięta a zarezerwowane obszary pamięci zwolnione poprzez automatyczny proces garbage collector.
Usunięcie aplikacji z karty aby usunąć aplikację z karty elektronicznej (wymazać pliki) należy w pierwszej kolejności wyłączyć serwis. Dopiero gdy instancja aplikacji zostanie wymazana, może nastąpić fizyczne usunięcie jej z pamięci karty elektronicznej
Architektura karty.net System operacyjny, Aplikacje, Środowisko uruchomieniowe., Loader czyli komponent softwarowy odpowiedzialny za pobieranie aplikacji wysyłanej do karty. Jest on odpowiedzialny za: sprawdzenie czy aplikacja w języku pośrednim IL jest bezpieczna, sprawdzenie czy aplikacja (plik) jest odpowiednio cyfrowo podpisany, upewnienie się, że wszystkie typy używane w aplikacji są obecna na karcie.
Ważną cechą elektronicznej karty.net jest zdolność do uruchamiania aplikacji jako część pewnego większego programu, systemu za pomocą mechanizmu zdalnego Remoting. Mechanizm ten umożliwia komunikację między procesami uruchomionymi na komputerze oraz karcie elektronicznej np. na tym samym komputerze lub dwóch połączonych siecią
.NET Remoting Dzięki metodzie RemotingServices.Marshal, która w celu umożliwienia komunikacji między procesami, tworzone jest specjalne PROXY dla obiektu serwera. W ten sposób uzyskujemy dostęp do metod oraz typów poprzez protokół transportowy ISO-7816-4. Komunikacja miedzy wieloma procesami aplikacji ma miejsce poprzez wcześniej ustanowione kanały dzięki klasom APDUSerwerChannel oraz APDUClientChannel odpowiedzialne za udostępnienie API dla programisty
.NET Remoting Aby wskazać zdalny obiekt należy wpisać jego ścieżkę URL komputera, na którym się znajduje oraz URI do którego procesu się odwołujemy np: apdu://gemalto Reflex USB v2:2222/cardservice Aby skomunikować się z kartą którą chcemy wybrać listy musimy użyć nazw zastrzeżonych : selfdiscover, promptdialog. Dzięki temu na ekranie komputera otrzymamy okienko z możliwością wyboru uruchomionego serwisu na zdalnej maszynie (karcie.net) do której próbujemy się połączyć
Podsumowanie Karty współpracujące z.net JavaCard Next Nowa generacja kart (z serwerem www) PRECYZYJNE KODOWANIE i TESTOWANIE!
Literatura i Linki W. Effing, W. Rankl. Smart Card Handbook, 2000, John Wiley & Sons M. Molski, M. Glinkowska, Karta elektroniczna - bezpieczny nośnik informacji, 2002, Mikom home.elka.pw.edu.pl/~pnazimek alt.technology.smartcards alt.satellite.tv.europe