Vous êtes sur la page 1sur 15

ED3 sur la Technologie Java Card

Samia Bouzefrane & Julien Cordry


Laboratoire CEDRIC
CNAM

Comment crire une applet ?

Exemple

du

porte-monnaie

lectronique

1. Comment crire une applet ?


Quatre tapes comprennent la phase de dveloppement dune applet:
1.
2.
3.
4.

Spcifier les fonctions de lapplet


Assigner des AIDs lapplet et au paquetage contenant la classe de lapplet
Concevoir les programmes de lapplet
Dfinir linterface entre lapplet et le terminal

Nous illustrons ces tapes travers lexemple du porte-monnaie.


2. Spcification des fonctions de lapplet :
Notre applet porte-monnaie va stocker de la monnaie lectronique et supporte les
fonctions de crdit, dbit et de contrle de la balance. Pour viter lutilisation
frauduleuse de la carte, la carte contient un algorithme de scurit. Cet algorithme
exige lutilisateur dentrer un PIN, une chane de 8 chiffres au plus. Lutilisateur de
la carte tape son PIN sur un keypad reli au terminal. Lalgorithme de scurit
provoque le verrouillage de la carte au bout de 3 tentatives choues lors de la saisie
du PIN. Le PIN est initialis lors de linstallation de lapplet.
Le PIN doit tre vrifi avant lexcution de toute transaction de crdit ou de dbit.
Pour simplifier, supposons que le maximum de la balance est de 32 767 (15 bits + 1
bit de signe) et que toute transaction de dbit ou de crdit ne peut dpasser 127 (7
bits + 1 bit de signe). Ainsi, les variables Java de type short et byte peuvent
reprsenter respectivement la balance et le montant de chaque transaction.
3. Spcification des AIDs :
Dans la technologie Java Card, chaque applet est identifie et slectionne par un
identificateur (AID). De mme, chaque paquetage Java est assign un AID. Cette
convention de nommage est conforme la spcification de la carte puce dfinie
dans lISO 7816.
Un AID est une squence doctets allant de 5 16 octets. Son format est donn au
Tableau 1.
Application identifier (AID)
National
registered
provider (RID)
5 octets

application Proprietary
application
extension (PIX)
0 to 11 octets
Tableau 1. Format de lAID
3

identifier

LISO gre laffectation des RIDs aux compagnies, chaque compagnie obtient son
propre et unique RID de lISO. Les compagnies grent laffectation des PIXs pour
leurs AIDs.
Les classes Java de lapplet sont dfinies dans un paquetage Java. Leurs AIDs
respectifs sont dfinies dans le Tableau 2.
Package AID
Champ Valeur

Longueur

RID

0xA0, 0x00, 0x00, 0x18, 0x50

5 octets

PIX

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x50 10 octets

Applet AID
Champ Valeur

Longueur

RID

0xF2, 0x34, 0x12, 0x34, 0x56

5 octets

PIX

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x41, 0x44, 0x41 10 octets
Tableau 2. AIDs fictifs pour lapplet et son paquetage

4. Dfinir les mthodes de lapplet :


Une applet Java Card doit tendre la classe javacard.framework.Applet. Cette
classe est une superclasse des applets rsident sur la carte. Elle dfinit les mthodes
courantes que doit utiliser une applet pour interagir avec le JCRE, lenvironnement
dexcution.
Tableau 3 liste les mthodes de type public et protected dfinies dans la classe
javacard.framework.Applet:

Method summary
public void

deselect ()

Called by the JCRE to inform the currently selected applet that another (or the
same) applet will be selected.
public
Shareable

getShareableInterfaceObject (AID client AID, byte


parameter)

Called by the JCRE to obtain a sharable interface object from this server applet on
behalf of a request from a client applet.
public
static void

install (byte[] bArray, short bOffset, byte bLength)

The JCRE calls this static method to create an instance of the Applet subclass.

public
abstract
void
protected
final void

process (APDU apdu)

Called by the JCRE to process an incoming APDU command.


register ()

This method is used by the applet to register this applet instance with the JCRE and
assign the default AID in the CAD file to the applet instance.
protected
final void

register (byte[] bArray, short bOffset, byte bLength)

This method is used by the applet to register this applet instance with the JCRE and
to assign the specified AID in the array bArray to the applet instance.
public
boolean

select ()

Called by the JCRE to inform this applet that it has been selected.
protected
final
boolean

selectingApplet ()

This method is used by the applet process() method to distinguish the SELECT
APDU command that selected this applet from all other SELECT APDU APDU
commands that may relate to file or internal applet state selection.

Tableau 3. Mthodes public et protected dfinies dans la classe


javacard.framework.Applet

La classe javacard.framework.Applet fournit un framework pour lexcution des


applets. Les mthodes dfinies dans la classe sont appeles par le JCRE lorsque celuici reoit des commandes APDU partir du lecteur (CAD :Card Acceptance Device).
Une fois le code de lapplet proprement charg sur la carte et li aux autres
paquetages se trouvant sur la carte, la vie de lapplet commence lorsquune instance
de lapplet est cre et enregistre au sein du JCRE. Une applet doit implmenter la
mthode install() pour crer une instance dapplet et doit enregistrer linstance au
sein du JCRE en invoquant une des mthodes register(). La mthode install()
prend un vecteur doctets comme paramtre. Ce vecteur contient les paramtres
dinstallation pour linitialisation et la personnalisation de linstance dapplet.
Une applet Java Card reste inactive jusqu ce quelle soit explicitement slectionne.
Lorsque le JCRE reoit une commande SELECT APDU, il consulte sa table interne pour
trouver lapplet dont lAID correspond celui spcifi dans la commande. Sil le
trouve, le JCRE prpare la slection de la nouvelle applet. Cette prparation se fait en
deux tapes: dabord, si une applet couramment slectionne est prsente en
mmoire, alors le JCRE la dslectionne en invoquant la mthode deselect().
Lapplet excute la mthode deselect() avant de devenir inactive. Le JCRE invoque
alors la mthode select() pour informer la nouvelle applet de sa slection. La
nouvelle applet effectue ventuellement une opration dinitialisation avant dtre
rellement slectionne. Lapplet retourne vrai la mthode select() si elle est prte
devenir active et traiter nimporte quelle commande APDU. Sinon, lapplet

retourne faux pour dcliner sa participation. La classe javacard.framework.Applet


fournit une implmentation par dfaut pour les mthodes select() et deselect().
Une sous-classe de la classe Applet peut redfinir ces mthodes pour associer un
autre comportement ces mthodes.
Une fois lapplet slectionne, le JCRE fait suivre toutes les commandes APDU (y
compris la commande SELECT) la mthode process() de lapplet. Dans la mthode
process(), lapplet interprte chaque commande APDU et excute la tche spcifie
par la commande. Pour chaque commande APDU, lapplet rpond au CAD en
envoyant une rponse APDU qui informe le CAD du rsultat du traitement de la
process()
de
la
classe
commande
APDU.
La
mthode
javacard.framework.Applet est une mthode de type abstract: une sous-classe
de la classe Applet doit redfinir cette mthode pour implmenter les fonctions de
lapplet.
Ce dialogue commande-rponse continue jusqu ce que une nouvelle applet soit
slectionne ou bien que la carte soit retire du CAD. Lorsquelle est dslectionne,
lapplet devient inactive jusqu sa prochaine slection.
La mthode getShareableInterfaceObject sert dans la communication interapplet. Elle est appele par une applet client qui demande, une applet serveur,
partager linterface dun objet. Limplmentation par dfaut de cette mthode est de
retourner null. Dans ce document, on ne sintressera pas la communication entre
applets.
tant donn que la commande APDU SELECT est aussi dirige vers la mthode
process(), la mthode selectingApplet() est utilise par la mthode process() de
lapplet pour distinguer entre la commande APDU SELECT qui slectionne cette
applet et les autres commandes APDU SELECT relatives la slection de fichiers ou
de ltat interne de lapplet.
5. Dfinir une interface entre une applet et le terminal:
Une applet qui tourne sur une carte puce communique avec lapplication en
utilisant le protocole APDU (Application Protocol Data Units dfini par lISO 7816).
Par essence, linterface entre lapplet et lapplication est un ensemble de commandes
APDU qui sont supportes aussi bien par lapplet que lapplication.
5.1 La notion dAPDU:
Les commandes APDU sont toujours des ensembles de paires. Chaque paire contient
une commande (command) APDU, qui spcifie une commande, et une rponse
(response) APDU, qui retourne le rsultat dexcution de la commande. Dans le
monde de la carte, les cartes sont ractives c--d quelles ninitient jamais des

communications mais se contentent de rpondre aux APDUs du monde extrieur.


Lapplication envoie une commande APDU via le lecteur (CAD). Le JCRE en
recevant une commande, slectionne une nouvelle applet ou bien passe la
commande une applet courante (dj slectionne). Lapplet courante traite la
commande et retourne une rponse APDU lapplication. Les commandes et
rponses APDU sont changes alternativement par la carte et le CAD.
Tableau 4 dcrit le format des commandes et rponses APDU.
Command APDU
Mandatory header
CLA

INS

Optional body
P1

P2

Lc

Data field

Le

CLA (1 byte): Class of instruction --- indicates the structure and format for a category of
command and response APDUs
INS (1 byte): Instruction code: specifies the instruction of the command
P1 (1 byte) and P2 (1 byte): Instruction parameters -- further provide qualifications to the
instruction
Lc (1 byte): Number of bytes present in the data field of the command
Data field (bytes equal to the value of Lc): A sequence of bytes in the data field of the
command
Le (1 byte): Maximum of bytes expected in the data field of the response to the command
Response APDU

Optional body

Mandatory trailer

Data field

SW1

SW2

Data field (variable length): A sequence of bytes received in the data field of the response
SW1 (1 byte) and SW2 (1 byte): Status words -- denote the processing state in the card
Tableau 4. formats des commandes et rponses APDU

5.2 Dfinir des commandes APDU:


Une applet Java Card doit supporter un ensemble de commandes APDU,
comprenant la commande SELECT APDU et une ou plusieurs commandes de
traitement dAPDUs.
La commande SELECT invite le JCRE slectionner une applet sur la carte.
Lensemble des commandes de traitement (process) dfinit les commandes que
lapplet supporte. Elles sont dfinies en accord avec les fonctions de lapplet.
La technologie Java Card spcifie lencodage de la commande SELECT APDU. Les
dveloppeurs sont libres de dfinir lencodage des commandes de traitement.
Cependant, les commandes de traitement doivent tre cohrentes avec la structure
dfinie au Tableau 4.

Dun point de vue structurel, la commande SELECT et les commandes de traitement


sont des paires de commandes et de rponses APDU.
Pour chaque commande APDU, lapplet doit dabord dcoder la valeur de chaque
champ de la commande. Si les champs optionnels sont inclus, lapplet doit aussi
dterminer leur format et leur structure. En utilisant ces dfinitions, lapplet sait
comment interprter chaque commande et lire chaque donne. Elle peut alors
excuter la tche spcifie par la commande.
Pour chaque rponse APDU, lapplet doit dfinir un ensemble de mots dtat pour
indiquer le rsultat du traitement de la commande APDU. Dans un traitement
normal, lapplet retourne un mot dtat contenant succs (0x9000, comme spcifi
dans lISO 7816). Si une erreur survient, lapplet doit retourner un mot dtat
diffrent de 0x9000 pour exprimer son tat interne. Si par contre le champ de donne
optionnel est inclus dans la rponse APDU, lapplet doit dfinir ce quelle doit
retourner.
Dans notre exemple, lapplet supporte les fonctions credit, debit, et checkbalance. De plus, elle doit supporter la commande VERIFY pour vrifier le PIN.
La commande SELECT ainsi que les 4 fonctions de traitement dAPDU sont illustres
dans le Tableau 5.

Commande APDU VERIFY


Commande APDU
CLA INS

P1

P2

Lc

Data field

0xB0 0x20 0x0 0x0 Longueur du PIN

Valeur du PIN

Le
N/A

Le code INS indique une instruction de vrification avec des paramtres nuls
Le champ donnes contient la valeur du PIN
Rponse APDU

Optional
data

Status
word

Meaning of status word

Pas de
donnes

0x9000

Traitement avec succs

0x6300

Echec de la vrification

Commande APDU CREDIT


Commande APDU
CLA INS

P1

P2

Lc

0xB0 0x30 0x0 0x0 1

Data field

Le

Valeur crditer

N/A

La champ donnes contient la valeur crditer


Rponse APDU

Optional
data

Status
word

Meaning of status word

N/A

0x9000

Traitement avec succs

0x6301

Exige la vrification du PIN

0x6A83

Valeur crditer invalide

0x6A84 Dpasse la valeur maximale autorise

Commande APDU DEBIT


Commande APDU
CLA INS

P1

P2

Lc

0xB0 0x40 0x0 0x0 1

Data field

Le

Valeur dbiter

N/A

Le champ donnes contient la valeur dbiter


Rponse APDU

Optional
data

Status
word

Meaning of status word

N/A

0x9000

Traitement avec succs

0x6301

Ncessite la vrification du PIN

0x6A83

Valeur dbiter invalide

0x6A85 Balance ngative

Commande APDU GET BALANCE


Commande APDU
CLA INS

P1

P2

Lc

0xB0 0x50 0x0 0x0 N/A

Data field

Le

N/A

Le champ donnes contient la valeur courante de la balance


Response APDU

Optional
data

Status
word

Meaning of status word

N/A

0x9000

Traitement avec succs

Tableau 5. Les commandes APDU de lapplet porte-monnaie

En plus des mots dtat dclars dans chaque commande APDU, linterface
javacard.framework.ISO7816 dfinit un ensemble de mots dtat qui signalent les
erreurs courantes des applets, comme par exemple la commande APDU concernant
lerreur du formatage.
6. Le support APDU dans la technologie Java Card:
La classe javacard.framework.APDU encapsule les commandes APDU. Elle fournit
une interface puissante et flexible qui permet aux applets de grer les commandes
APDU. La classe APDU est conue pour cacher les complexits du protocole, afin
que les dveloppeurs dapplet se concentrent davantage sur les dtails de
lapplication.
Lorsque le JCRE reoit une commande APDU, il encapsule la commande dans un
objet APDU quil passe la mthode process() de lapplet courante. Lobjet APDU
comporte un vecteur doctets qui contient le message APDU.
Lapplet traite une commande APDU en invoquant des mthodes sur cet objet
APDU. En gnral, lapplet effectue les tapes suivantes:
tape 1. Extraire le buffer APDU:
Lapplet invoque la mthode getBuffer() afin dobtenir une rfrence au buffer
APDU, qui contient le message. Lorsque lapplet reoit lobjet APDU, seuls les 5
premiers octets sont disponibles dans le buffer. Il sagit dans lordre des octets CLA,
INS, P1, P2, et P3. Loctet P3 dsigne loctet Lc, si la commande possde des donnes
optionnelles. Lapplet peut vrifier les octets entte pour dterminer la structure de la
commande et linstruction spcifie par la commande.
tape 2. Recevoir des donnes:
Si la commande APDU contient des donnes optionnelles, lapplet doit diriger lobjet
APDU vers la rception de donnes entrantes en invoquant la mthode
setIncomingAndReceive(). Les donnes sont lues dans le buffer APDU en suivant
lordre des 5 octets dentte. Le dernier octet de lentte (Lc) indique la longueur des
donnes entrantes. Si le buffer APDU ne peut contenir toutes les donnes, lapplet
peut traiter les donnes en fragments, ou bien le copier vers un buffer interne. Dans
les deux cas, elle doit faire appel de manire rptitive la mthode receiveBytes()
afin de lire les donnes additionnelles partir du buffer APDU.
tape 3. Renvoyer des donnes:
Aprs avoir trait une commande APDU, lapplet peut retourner des donnes
lapplication sous forme de rponses APDU. Lapplet doit dabord faire appel la

10

mthode setOutgoing() pour obtenir la longueur de la rponse (Le). Le est spcifi


dans la commande APDU associe la rponse APDU.
Ensuite, lapplet appelle la mthode setOutgoingLength()pour informer le CAD de
la longueur relle des donnes de la rponse. Lapplet peut transfrer les donnes
vers le buffer APDU et appeler la mthode sendBytes() pour envoyer les donnes.
La mthode sendBytes() peut tre appele plusieurs fois si le buffer APDU ne peut
pas contenir toutes les donnes retournes.
Si les donnes sont stockes dans un buffer interne, lapplet invoque la mthode
sendByteLong() pour envoyer les donnes partir du buffer.
Si les donnes de la rponse sont trop courtes pour tenir dans le buffer APDU, la
classe APDU fournit une mthode approprie: setOutgoingAndSend(). Cette
mthode est une combinaison de setOutgoing, de setOutgoingLength et de
sendBytes. Nanmoins cette mthode ne peut tre invoque quune seule fois, et
aucune mthode denvoi ne peut tre appele aprs.
tape 4. Renvoyer le mot dtat (word status):
Aprs un succs de la mthode process(), le JCRE envoie automatiquement 0x9000
pour indiquer un traitement normal. A nimporte quel point, si lapplet dtecte une
erreur, lapplet peut lever lexception ISOException en appelant la mthode statique
ISOException.throwIt(short reason). Le mot dtat est spcifi dans le paramtre
reason. Si lexception ISOException nest pas gre par lapplet, elle sera attrape
par le JCRE. Le JCRE extrait le code de reason code et lenvoie comme mot dtat.
7. Cas particulier du PIN
Le package javacard.framework fournit une interface PIN pour la manipulation du
PIN. La classe OwnerPIN (qui implmente linterface PIN) reprsente la PIN
propritaire. Elle implante la fonctionnalit "Personal Identification Number et
fournit la possibilit de mettre jour le PIN.

Constructor Summary
OwnerPIN(byte tryLimit, byte maxPINSize)

Constructor.
Les mthodes de la classe OwnerPIN sont les suivantes :

Method Summary
boolean check(byte[] pin, short offset, byte length)

11

Compares pin against the PIN value.


byte getTriesRemaining()
Returns the number of times remaining that an incorrect PIN can be
presented before the PIN is blocked.
protected getValidatedFlag()
boolean
This protected method returns the validated flag.
boolean isValidated()
Returns true if a valid PIN has been presented since the last card reset
or last call to reset().
void reset()
If the validated flag is set, this method resets it.
void resetAndUnblock()
This method resets the validated flag and resets the PIN try counter to the
value of the PIN try limit.
protected setValidatedFlag(boolean value)
void
This protected method sets the value of the validated flag.
void update(byte[] pin, short offset, byte length)
This method sets a new value for the PIN and resets the PIN try counter
to the value of the PIN try limit.

8. Construire le code de lapplet:


Une fois la phase de conception de lapplet est finie, la seconde phase consiste
crire le code de lapplet.
package cnam;

Package

import javacard.framework.*;
public class APurse extends Applet {

Une applet est une instance dune classe qui


hrite de : javacard.framework.Applet.

/* declaration de constantes
// code CLA pour
final static byte APP_CLA =
(byte)0xB0;

CLA identifie une famille de commandes.

*/

// codes INS des commandes APDU


final static byte VERIF_INS =
(byte)0x20;
final static byte CREDIT_INS =
(byte)0x30;
final static byte DEBIT_INS =
(byte)0x40;
final static byte GET_BALANCE_INS =
(byte)0x50;

INS dfinit le type dinstruction

Dclarer la balance maximale et la valeur


maximale de la transaction.

// Poids le plus faible a droite


final static short MAX_BALANCE =

12

(short)0x7fff;
final static byte
MAX_TRANSACTION_AMOUNT=127;
// nb de tentatives
final static byte PIN_NB_LIMIT =
(byte)0x03;
// taille maximale du PIN
final static byte
MAX_PIN_SIZE=(byte)0x08;

Les paramtres du PIN

// chec de la vrification du PIN


final static short
SW_VERIFICATION_FAILED = 0x6300;

Les Status Words

// indique que la transaction debit ou


credit
// necessite la verification du PIN
final static short
SW_PIN_VERIFICATION_REQUIRED = 0x6301;
// transaction invalide car
// montant>MAX_TRANSACTION_AMOUNT ou
montant<0
final static short
SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
// indique que la balance dpasse le
maximum
final static short
SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
//indique que la balance est devenue
ngative
final static short SW_NEGATIVE_BALANCE
= 0x6A85;

/* declaration de variables
dinstances */
OwnerPIN pin;
short balance;
private APurse (byte[] bArray, short
bOffset, byte bLength){
//cre un objet qui est le PIN de la
carte
pin = new
OwnerPIN(PIN_NB_LIMIT,MAX_PIN_SIZE);
// les paramtres dinstallation
comprennent
// linitialisation de la valeur du
PIN
pin.update(bArray, bOffset, bLength);
register();
} // fin du constructeur

Constructeur priv de la classe APurse


- alloue de la mmoire aux objets crs
- enregistrement de lapplet auprs du JCRE
laide de son AID
La mthode update() affecte une nouvelle
valeur au PIN et initialise le nb de tentatives de
PIN avec le nb limite PIN_NB_LIMIT.

Mthode install invoque par le JCRE pour


public static void install(byte[]
installer lapplet
bArray, short bOffset, byte bLength) {

13

// cre une instance de lapplet APurse


new APurse(bArray, bOffset, bLength);
} // fin de la mthode install

public boolean select() {


Mthode appele par le JCRE pour indiquer la
// lapplet refuse detre selectionnee slection de lapplet
// si le PIN est bloque
if ( pin.getTriesRemaining() == 0 )
return false;
else return true;
}// fin de la mthode select

Cette mthode est appele par le JCRE pour


effectuer une ventuelle dsallocation.

public void deselect() {


// remise zero de la valeur du
PIN
pin.reset();
}

public void process(APDU apdu) {


Aprs slection dune apple, le JCRE dirige les
// le buffer qui recupere lobjet APDU commandes APDU vers la mthode process qui
// ne contient au depart que les octets les traite. Lobject APDU est dtenu et
// [CLA, INS, P1, P2, P3]

maintenu par le JCRE.

byte[] buffer = apdu.getBuffer();

Le JCRE passe aussi la commande SELECT


APDU lapplet.

if (selectingApplet()) return;

Lexception renvoye en cas derreur est


explicite dans les status word (SW1, SW2).
Une exception non capture par lapplet sera
capture par le JCRE.

// vrifie le CLA des commandes

????
// identifier les codes INS

Les fonctions principales qui ralisent laction


spcifie par la commande APDU avec un
retour dune rponse APDU.

???
} // fin de la methode process
private void credit (APDU apdu) { ??}

La mthode credit contrle tous les cas en


retournant des exceptions en cas derreur.
Lobjet APDU contient le montant crditer.

private void debit (APDU apdu) { ???}

Lobjet APDU contient le montant dbiter.


private void getBalance (APDU apdu) {
???}

14

La mthode getBalance retourne la balance


dans le champ donnes de la rponse APDU.
Etant donn que le champ donnes est
optionnel, lapplet doit informer explicitement

le JCRE des donnes additionnelles.


private void verify(APDU apdu) { ???}

} // fin de la classe APurse

Le PIN est utilise pour protger la carte puce.


Le nombre de tentatives choues peut tre
enregistr. Ainsi la carte sera bloque si ce
nombre dpasse le nombre maximal autoris.
En cas de succs et aprs slection de lapplet le
PIN doit tre vrifi avant toute instruction
excute par lapplet.

Question1
Utilisez lenvironnement Eclipse pour gnrer votre applet en lui associant un AID.
A partir des indications donnes dans le tableau ci-dessus, crire une premire applet
qui nutilise pas de PIN. Complter la mthode process() de manire ce quelle
puisse reconnatre les diffrentes instructions et quelle puisse lancer les mthodes
prives credit(), debit() ou getBalance() en fonction du code instruction lu.
Compilez lapplet pour obtenir un fichier .cap. Installer lapplet sur la carte et
interagir avec la carte en testant les commandes APDU.
Question 2
Reprendre la mme applet en intgrant la gestion du PIN.
Rfrences
Zhiqun Chen, How to write a Java Card applet: A developer's guide,
http://www.javaworld.com/javaworld/jw-07-1999/jw-07-javacard.html.
Pierre Paradinas, Support de cours sur Java Card , UV de Systmes Enfouis et
Embarqus, Valeur C, Laboratoire CEDRIC, CNAM. Accessible via :
http://deptinfo.cnam.fr/~paradinas/cours/ValC-IntroJavaCard.pdf
Global Platform, Card Specification :
http://www.globalplatform.org/specificationform2.asp?id=archived
API Java Card : http://java.sun.com/products/javacard/htmldoc
ED1 et ED2 : http://cedric.cnam.fr/~bouzefra/javacard.html

15

Vous aimerez peut-être aussi