Thibaut Colar |
DEPARTEMENT INFORMATIQUE |
Sécurisation de l'accès à une base de donnée par une carte à puce |
|
Rapport de stage Année Spéciale 97/98 |
|
Thibaut Colar |
DEPARTEMENT INFORMATIQUE |
Sécurisation de l'accès à une base de donnée par une carte à puce |
|
Rapport de stage Année Spéciale 97/98 |
|
SOMMAIRE
Page 01
Sommaire
Sommaire |
01 |
|
|
Remerciements |
03 |
|
|
Introduction |
05 |
|
|
Le projet Qualidiab |
07 |
- Présentation du projet |
08 |
- Mise en place de la base de donnèes |
08 |
- Conversion des fichiers delphi |
08 |
|
|
Démonstration de l'accès à une base de donnée distante sécurisé par une carte à puce |
10 |
- Introduction |
11 |
- Matérialisation du problème |
11 |
- Solution logicielle |
11 |
- Présentation de la MPCOS |
15 |
Décomposition des problèmes |
17 |
- Partie commune aux deux programmes Java |
17 |
- Le CGI Java |
18 |
- Le programme Java |
19 |
- Le programme C |
20 |
- Evolutions et perspectives |
22 |
- La norme Edifact |
23 |
|
|
Conclusion |
25 |
Page 02
REMERCIEMENTS
Page 03
Remerciements
Je tiens à remercier Marie-Pierre Van-Hoecke, qui m'a encadrée tout au long de ce stage, est qui m'a apporté sa connaissance des cartes à puce et qui a su m'aider à analyser les problèmes, ainsi que les autres personnes du LIFL qui m'ont apporté leur soutien.
Mes remerciements vont aussi au Proffesseur G.Grimonprez avec lequel j'ai pu rester en contact, malgrès la période estivale et qui m'a apporté son soutien aussi bien en programation C et Java, qu'en cartes à puce.
Page 04
INTRODUCTION
Page 05
Introduction
Mon stage, d'une durée de 10 semaines s'est déroulé au LIFL (laboratoire d'Informatique Fondamentale de Lille)., laboratoire de recherche CNRS/Université de sciences de lille.
J'y ai travaillé sur le projet QualiDiab (Amélioration du suivi des diabétiques).
Après avoir pris connaissance de l'ensemble du projet, j'ai participé à la mise en place d'une base de donnée Oracle au CERIM (Centre d'Informatique et de Recherche en Informatique Médicale de l'université de Lille), la base de donnée Internationale déstinée à contenir les fiches anonymisées des patients diabétiques.
Après création de la base, il était necessaire d'y insérer les données antérieures, qui etaient au format d'enregistrement des fichiers Delphi.
Il a donc été nécessaire de créer un programme de conversion du format delphi vers le format de la base Oracle, j'ai écrit ce programme en Pascal, ce qui permettait de récupérer les structures delphi.
Cette base de donnée étant notament destinée à des fins statistiques, il était necessaire que l'on puisse y accéder.
Toutefois L'accés à ces données devait être sécurisé et donné uniquement aux personnes autorisées (Médecins…), J'ai eu à réaliser l' accés distant (par internet) à cette base de données, sécurisé par une carte à puce contenant les droits d'accès de la personne détentrice.
Page 06
LE PROJET QUALIDIAB
Page 07
Le projet QualiDiab
Qualidiab est la réponse Française commune à deux projets Européens sountenu par l'OMS, il est composé de Diabcare et Diabcard.
Un mois par an depuis cinq ans les hopitaux et diabétologues de ville remplissent une fiche pour chaque patient diabétique qui passe dans leur service.
Cette année la France étend la collecte des données aux médecins généralistes.
Qualidiab est une plateforme logicielle qui permet:
Mise en place de la base de donnée Oracle
Cette base de donnée (internationale) est basée au CERIM à la faculté de médecine de Lille.
Je ne conaissais pas du tout Oracle, une personne du CERIM m'a donc expliqué durant une journée le fonctionnement global de ce SGBD.
Conversion des fichiers delphi
La campagne Qualidiab ayant commencé en 93, cinq années de données devaient être récupérées.
Ces données qui avaient été tout d'abord notées sur feuilles papier, étaient ensuite saisies par un organisme spécialisé, grâce à un logiciel, en donnée informatiques.
Ce programme était écrit en delphi et les données étaient simplement enregistrées au format d'enregistrement de ce langage.
Le probleme étant qu'Oracle ne peut pas lire directement ce format d'enregistrement, une conversion des données était donc necessaire.
Page 08
Le format de destination est simplement le format texte avec le ';' comme séparateur de champ et le '\n' (retour chariot) comme séparateur d'enregistrement, ce format étant lisible, à travers un outil d'Oracle et permettant une relecture directe des données en cas de vérification.
Le programme de conversion a été écrit en Turbo Pascal, langage que je conaissais déjà un peu, ce qui a permis de récupérer directement les enregistrements (les types de données élémentaires de delphi étant les mêmes que ceux du pascal)
Toutefois ces données ne pouvaient pas simplement être écrites dans un fichier texte, en effet la plupart demandaient une conversion préalable, notamment en raison de changement dans la codification.
Par exemple, une grande partie des questions étaient de type Yes/No/Missing et codées respectivement 1/2/0 sur un byte, la nouvelle codification est 0/1/2.
D'autres questions dont la codification créait une perte de donnée ont étaient revues, par exemple à une question les réponses de type case à cocher étaient *avant *après, dans ce cas comment savoir, lorsque aucune des deux cases n'a été cochée si cela signifie ni avant ni après ou que la question n'a pas était renseignée, ce type de questions a donc du être transformée en *avant: oui non, *après : oui non.
Chaque fiche comprenant 92 champs il n'était pas évident de ne pas faire d'erreur, d'autant plus que chaque erreur serait répercutée dans les 20000 fiches converties.
Le programme de conversion ne contient en fait que l'ouverture du fichier de donnée delphi, une boucle principale qui lit chaque enregistrement, convertit ses champs puis les enregistre au format texte dans un fichier destination, et referme le fichier.
Page 09
DEMONSTRATION DE L'ACCES A UNE BASE DE DONNEE SECURISE PAR UNE CARTE A PUCE
Page 10
Démonstration de l'accès à une base de donnée distante par une carte à puce.
Introduction:
Pour permettre la sécurisation de l'accés à la base de donnée (par une identification de la personne demandeuse), la carte à puce est le moyen le plus sûr, en effet la clé secrète y étant stockée ne peût en sortir.
Une carte à puce a donc été utilsée en tant que sécurisation, la carte prévue en premier lieu était une CPS (Carte de Proffesssionel de Santé), toutefois faute de posseder le kit de développement, une carte MPCOS (Multi-application Payment Chip Operating System de Gemplus) a été utilisée en remplacement.
Matérialisation du probléme:
Il fallait qu'un ordinateur client puisse se connecter à un serveur(http) capable de transmettre les requêtes à la base de donnée Oracle, puis de lui renvoyer les réponses.
En outre de manière a sécuriser l'accès, l'identification, l'autentification ainsi que la reconnaissance du profil du client devait etre faite via sa carte à puce personnelle (insérée dans son lecteur).
Solution logicielle:
J' ai en premier lieu décidé de réaliser la partie client-serveur, j'ai choisi pour cela le langage Java, qui posséde des fonctions simples et éfficaces dans ce domaine.
Le client posséde donc un programme java destiné à communiquer avec le serveur, via un CGI en Java lui aussi.
Il a ensuite fallu établire la connexion (locale) entre le programme java du client et son lecteur de carte (et donc l'OS carte) , les librairies de la carte MPCOS étant écrites en C 16 bits ne pouvaient être utilisées directement par le programme java, les appels aux fonctions de la carte ont donc été réalisées par un programme c, lui-même appelé par le programme java.
Enfin, les requêttes à la base Oracle seront faites par l'intermédiaire du CGI Java, déjà cité, grace aux fonctions JDBC founies par Java.
De manière à avoir une vue globale de l'application, voici tout d'abord son schéma de principe (correspondances entre les éléments physiques et logiciels), suivi d'un chronogramme décrivant l' interaction dans le temps des differents programmes qui la composent:
Page 11
Carte |
Programme C |
Programme Java |
Browser |
CGI |
Oracle |
|
|
En Tache de fond: Ouverture d'un port |
|
En attente: Démon HTTP |
|
|
|
|
Appel du CGI. |
|
|
|
|
|
|
Ouverture du port, Création socket (selon Trace.log) |
|
|
|
Détection connexion Avec le CGI |
|
Connexion avec le programme Java |
|
Connexion établie entre le programme java et le CGI.
En cas d'erreur lors de l' ouverture des ports ou de la connexion, le CGI affiche un message d'erreur dans le browser et s'arrete.
Page 12
|
|
|
|
Demande d'authentification de la carte. |
|
||
|
|
Réception de la demande d'autentification (via la socket)->appel C |
|
|
|
||
|
Ouverture channel avrc la carte, demande clé secrete. |
|
|
|
|
||
Lecture clé secréte. |
|
|
|
|
|
||
|
Renvoi de Ack ou Nak |
|
|
|
|
||
|
|
Envoi du Ack ou Nak au CGI |
|
|
|
||
|
|
|
|
Si NAK message d'erreur, fin. Si ACK demande d'identification du profil. |
|
||
|
|
Demande d'identification au prg C |
|
|
|
||
|
Demande du code secret utilisateur. |
|
|
|
|
||
Verification code secret, lecture du profil ds un fichier. |
|
|
|
|
|
||
|
Envoi profil ou Nak au CGI |
|
|
|
|
Page 13
Carte |
Programme C |
Programme Java |
Browser |
CGI |
Oracle |
|||||
|
|
|
|
Si Nak: message d'erreur, fin Si Ack envoi du profil comme login à oracle. |
|
|||||
|
|
|
|
|
Ouverture session. |
|||||
|
|
|
|
Creation page html |
|
|||||
|
|
|
Formulaire de saisie |
|
|
|||||
|
|
|
|
Fabrication requette Sql |
|
|||||
|
|
|
|
|
Traitement requette |
|||||
|
|
|
|
Fabrication page de réponse |
|
|||||
|
|
|
Affichage réponse |
|
|
|||||
|
|
|
|
|
Si fin, fermeture session. |
|||||
|
|
|
|
Déconnection de la socket. |
|
|||||
|
|
Fermeture du port et Retour à l'état d'attente. |
|
|
|
Page 14
Presentation de la carte MPCOS
La Carte MPCOS (Multi-application Payment Chip Operating System) fait partie de la famille des cartes COS de Gemplus.
Son systeme d'exploitation est stocké dans une mémoire de type EEPROM d'une taille de 16 kb, sa structure de donnée est basée sur la norme ISO 7816-4. Il existe des cartes de 8,32 et 64 Kb de RAM.
L'echange de données se fait normalement par le protocole T=0, même s'il est possible d'utiliser le protocole T=1. La Vitesse de transfert pouvant etre fixée jusqu'à 115200 bauds.
La structure de donnée de la carte MPCOS ne comporte que deux niveaux de hiérarchie. La racine de cette structure est le MF (Master File), Il peut contenir jusqu'à 63 fichiers.
Ces fichiers sont de deux types : les DF(Dedicated Files : Repertoires) et les EF(Elementary Files : Fichiers). Un DF peut contenir des EF (jusqu'à 63) mais pas de DF puisqu'il n'y a que deux niveaux de hiérarchies. Les EF, quant à eux, contiennent les données.
Les DF peuvent être de deux types : ISO ou PCOS(Gemplus), Les EF dépendent du type du fichier (MF ou DF) dont ils font partie.
L'accés aux fichiers de la carte est sécurisé par des codes secrets contenus dans des fichiers de codes secrets (Efsc), chacun de ses Efsc pouvant contenir jusqu'à 8 codes numérotés de 0 à 7.
Chaque Répertoire(MF ou DF) peut contenir un (et un seul) fichier d'Efsc.
Tout fichier (MF, DF, EF) possède des conditions d'accés (en lecture/eciture/modification) stockées dans 2 bytes de leur descripteur on y trouve :
La carte enregistre les codes secrets soumis avec succés dans des registres d'autorisation(permet de savoir a tout moment si l'utilisateur a été validé ou non).
Page 15
Un registre d'autorisation est d'une longueur de 8 bits et est stocké en RAM, la carte MPCOS en posséde deux, le premier alloué au MF, le second au DF actuellement séléctionné.
La carte MPCOS possède dans son systéme d'exploitation un jeu d'instructions relativement important.
Il existe deux grand types d'instructions : celles d'administration et celles de paiement.
Les commandes administratives peuvent étres de deux types :
Il existe de plus, des fonctions de cryptage qui permettent de sécuriser les transmissions, par exemple la création d'une clé de session qui permet le secure messaging et le cryptage des commandes de paiement.
Page 16
Décomposition des programmes:
Partie commune aux deux programmes java (client & cgi)
Je presente ces programmes ensemble tout d'abord car ils possédent une classe commune qui leur permet de communiquer enssemble.
Cette classe que j'ai créée ets nommée masocket et s'occupe de la gestion des communications entre ces deux programmes.
Cette classe déclare une socket ainsi que des flu d'entrée sortie (DataInputStream et PrintStream).
Constructeur: masocket()
Elle posséde les méthodes suivantes:
La fonction attenetlien() a pour fonction d'attendre qu'une requêtte de connexion soit emise puis renvoyer un message d'état.
La fonction connecter() permet de connecter le CGI au client par une socket, connaissant son IP et le numéro de port , puis retourne l'état de sortie(réussite ou echec) .
La fonction connecterFlux permet de connecter les flux d'entrées(DataInputStream) au flux de sorties (PrintStream), puis retourne l'état de sortie.
La fonction écrire() permet d'emettre une chaine dans le canal de communication.
La fonction lire() permet de lire une chaine dans le canal de communication.
Page 17
Le CGI Java (coté serveur HTTP)
Ce Cgi (Programme lancé par le serveur Http suite à une requêtte faite par le browser) est écrit en java (il est pour l'instant lancé via un .bat car je n'ai pas réussi à associè l'extension .class au programme javaw).
Il est chargé des communications avec le client et de la communication avec la base de donnée.
Il comporte les méthodes suivantes:
La fonction liretracelog() a pour fonction d'aller lire dans le fichier Trace.log du serveur l'addresse IP de la derniére machine s'étant connectée, c'est à dire celle qui a lancé le CGI courant.
La fonction questionnaire affiche la page déstinée à créer les requêttes Html dans le browser.
La fonction erreur renvoie tous les messages d'erreurs, que l'erreur ait est eu lieux dans le CGI ou que le message ai été passé par le programme java ou le programme C, dans le browser.
J'ai fait ce choix de maniere à pouvoir informer directement l'utilisateur sur l'état d'avancement actuel.
Le Programme principal
L'appel du Cgi provoque la création d'un objet de type cgi par appel de son constructeur.
Ce cgi commence par appeler la methode liretracelog() de manière à récuperer l'adresse IP de la machine appelante, elle peut ainsi se connecter à celle-ci par la methode connecter() de la classe masocket via le port 9090.
Une fois la connexion établie, il faut encore connecter les flux ensemble par appel à la méthode connecterFlux de la classe masocket.
Le programme va maintenait attendre la valeur de retour du programme java lui informant d'une erreur éventuelle (par la methode lire de la classe masocket), s'il y a eu erreur le cgi appelle la méthode erreur() puis se termine, sinon il appelle la méthode questionnaire qui devra créer les requêttes cgi et les communiquer à Oracle.
Page 18
Le programme java (coté client)
Ce programme se comporte comme un démon (il tourne en tâche de fond).
L'objet de base de ce programme nommé demon est du type Frame (Il en hérite), ceci permettant d'afficher les informations d'avancement dans cette fenêtre, de plus il implemente la classe ActionListener de maniere à pouvoir gerer le bouton de sortie du programme.
Constructeur demon(int : numero de port)
Voici le déroulement de ce programme:
Premièrement, le programme créé un nouvel objet de type demon avec le numéro de port fixé à 9090 (par appel au constructeur).
L'appel au constructeur de cet objet appelle implicitement le constructeur de l'objet dont il hérite, c'est à dire le constructeur par defaut de la classe Frame.
Differentes fonctions, héritées de la classe Frame, sont ensuite appelées de manière à avoir une fenêtre (visible) de titre "Application cliente carte CPS" comportant un champ de texte et un bouton d'échappement.
Une fois ces initialisation graphique éfféctuées, commence le travail d'établissement de la communication.
Tout d'abord, la création d' un objet ServeurSocket sur le port 9090 destiné à recevoir la connexion établie par le CGI puis appel de la methode attentelien de l'objet de type masocket avec en parametre la ServeurSocket precedemment citée, ceci ayant pour effet d'attendre la connexion du cgi.
Une fois que le CGI s'est connecté (en ayant appelé la méthode connecter() de la classe masocket) les deux programmes sont reliés par un canal de communication auquel il faut toutefois encore connecter le flux d'entrée sortie, cela se faisant par l'appel à la méthode connecterFlux() de la classe masocket.
Vient maintenant l'appel à la methode locale traiterRequetteCgi(), cette methode crée tout d'abord un objet VerifPassword, lui aussi de type Frame.
Cet objet est composé d'un label de demande de mot de passe, d'un champ de saisie de type code secret (caractère d'echo : *) et d'un bouton de soumission.
La méthode VerifPassword attend pendant ce temps la fin de la saisie par une vérification régulière de l'état de la saisie par l'intermédiaire d'un Thread se répétant 10 fois par secondes.
Ensuite, il y a appel à la méthode authentification() avec comme paramètre le mot de passe précedemment saisi.
La méthode authentification(String) lance le programme C (voir description ci dessous) avec en paramètre le mot de passe, par l'intermédiaire d'un objet de type process, en attend la fin, puis renvoie la valeur de retour de ce process à la fonction traiterRequetteCgi() qui la passe à son tour au Cgi par l'intermediaire de la fonction écrire de la classe masocket, pour que celui ci puisse envoyer un message d'état au browser.
Page 19
Le Programme C
Le fait que ce programme soit en C était nécessaire, les librairies fournies avec la carte MPCOS, par Gemplus, ayant été écrites pour du C 16 bits.
Les fonctions:
- INT16 identifiant du channel(Channel ID) openchannel() INT16 est défini par le fichier d'entéte de Gemplus.
La fonction openchannel() sert à ouvrir une voie de communication avec le lecteur, elle utilise pour cela les constantes prédifinies suivantes (clauses DEFINE) IFD_TYPE Type du lecteur, IFD_MODE Type de connexion, IFD_PORT Nom du port, IFD_BAUD Vitesse de transmission, IFD_IT Numéro de l'interuption.Elle retourne soit un code d'erreur, soit l'identifiant du channel qui a pu être ouvert.
La fonction opensession() utilise la constante ICCTYPE Type de carte (ici ISO), Elle ouvre une session avec la carte et renvoie un code d'erreur ou 0.
La fonction authentification() est utilisée pour verifier que l'on est en présence d'une carte valide, elle fait premierement appel à la fonction G_MPC_Selkey(INT16 Channel ID, INT16 keylevel, WORD16 keyfilenum, INT16 keynumber, WORD8[8] pcrandom, WORD8[4] cardresult, WORD8[8] cardrandom)
Page 20
Il faut ensuite faire appel à G_MPC_SetSecureSessionKey(INT16 SMType, INT16 keylevel, WORD16 keyfilenum, INT16 keynumber, WORD8[8] pcrandom, WORD8[8] cardrandom, WORD8[4] cardresult, WOR8[16] keyref)
Le pc effectue un cryptage local, puis le compare à celui précédemment fourni par la carte.
Si la comparaison réussit, la carte est authentifiée.
La fonction verifcode() permet de comparer le code secret fourni par l'utilisateur (via le programme java) à celui contenu dans un fichier de code secret de la carte, elle utlise pour cela la fonction G_MPC_VerifCode(WORD16 channel ID, INT16 codenumber, WORD8[] codevalue).
Si le code secret présenté est valide, la fonction peut lire dans la carte le fichier contenant le profil de l'utilisateur.
Cette fonction retourne ensuite soit un NAK soit un profil d'utilisateur lu dans un fichier de la carte.
La fonction closesession() ferme la session associée au channel et retourne soit 0 soit un code d'erreur.
La fonction closechannel() ferme le channel et libére donc le port, elle retourne elle aussi soit 0 soit un code d'erreur.
Main du Programme C
Il récupère le mot de passe utilisateur, qui lui est passé en paramétre par le programme java, il appelle ensuite openchannel, opensession, authentification, verifcode, closesession, closechannel.
A chacun des appels précédents un code retour est renvoyé, au moindre problème (par exemple pas de carte), le programme termine tout de suite en renvoyant un code d'erreur, qui sera interprété par le code java puis passé au CGI, qui pourra informer efficacement le client par un message d'erreur via son browser.
S'il n'y a pas d'erreur, le programme renvoie un profil utilisateur, qui sera utilisé par Oracle comme nom de login, en effet il était difficile de lister autant d'utilisateurs Oracle que de porteurs de carte.
Nous avons donc choisi de le regrouper par "profil"
De plus c'est le Cgi qui génére le password correspondant au profil, ainsi aucunmot de passe ne transite sur le réseau..
Page 21
Evolutions et perspectives
La partie accés à la base de données n'a pu être traitée faute de temps, cela reste donc à faire
L'alimentation future de la base devrait permettre de recevoir des messages à la norme EDIFACT (voir la description rapide de cette norme en page suivante), ceci permettrait une mise à jour, en ligne, de la base par les centres des différents pays concernés par le projet.
Page 22
LA NORME EDIFACT
EDI signifie Echange de données informatisées, la norme EDIFACT(ONU) a pour but de standardiser les échanges de messages, l'utilisation de cette norme a notamment été recommandée par l'état français à ses administrations.
Les messages sont délivrés par Edifact Board ou EdiFrance dans notre pays.
EDIFACT permet la liason de plusieurs éléments différents:
Ceci est censé permettre la portabilité du message à travers le monde.
Le messsage EDIFACT recherche l'exhaustivité et l'universalité, c'est pourquoi il est lourd, lent, difficile à normaliser, pénible à utiliser, et très vite obsolète au regard des nouvelles technologies.
Il est possible d'utiliser les messages EDIFACT sur internet car ils sont encapsulables sous TCP/IP.
Des améliorations de la norme Edifact sont en cours
( Voir : http://www.geocities.com/wallstreet/floor/5815).
Page 23
CONCLUSION
Page 24
Conclusion
Ce stage m'a permis d' acquérir une bonne connaissance des cartes à puce, ainsi que de la programation client-serveur en java.
J' ai aussi eu à mettre en relation un programme C et un programme Java durant mon stage, et je regrette d'avoir perdu prés de quinze jours pour arriver a trouver le compilateur C adequat à la création d'un programme utlisant les librairies Gemplus.
Pour terminer,
Page 25