Brevet FR3010815A1 — publié le 20150320

DOMAINE DE L'INVENTION La présente invention concerne le domaine de la sécurisation informatique et plus particulièrement un procédé et un système de sécurisation d'un environnement d'exécution informatique. CONTEXTE DE L'INVENTION La sécurité des systèmes informatiques est soumise à rude épreuve par une grande variété d'attaques développées au cours des dernières décennies. Les attaques par confusion de type ont été développées pour mettre à mal la sécurité des environnements d'exécution informatiques reposant sur des données typées, en particulier lorsqu'un type de donnée, c'est-à-dire avec un type particulier, est fortement protégé. C'est le cas par exemple dans les plateformes Java Card conformes à la norme ISO 7816 - Java Card 3.0, où des données de type référence à un objet ou une applet sont mémorisées. Les données de type référence contiennent généralement une valeur d'adresse mémoire, par exemple Ox7FFF, indiquant à quelle adresse mémoire est stocké l'objet ou l'applet auquel elles font référence. Une telle donnée de type référence est généralement attribuée/affectée par l'environnement d'exécution informatique, par exemple la machine virtuelle Java dans les plateformes homonymes, à tout nouveau objet instancié à partir d'une classe de définition. Généralement l'affectation est incrémentale. Cependant, la manipulation d'un objet ou d'une applet est interdite dans ces plateformes Java Card, en empêchant d'accéder aux données de type référence à cet objet ou applet, notamment en interdisant certaines instructions basiques ou bytecodes (autrement connu sous la terminologie pseudo-code Java) sur ces données de type référence. On rappelle ici que le langage de programmation Java utilisé pour la plateforme Java Card est un langage intermédiaire de programmation permettant un développement d'applications indépendamment des architectures matérielles sur lesquelles doivent être exécutées ces applications. Une application écrite dans le langage de programmation Java peut être compilée en pseudo-code Java, c'est-à-dire dans un langage intermédiaire de programmation exécutable par une machine virtuelle Java sur des plateformes ayant des caractéristiques matérielles différentes. A contrario, les données de type primitives, c'est-à-dire ne faisant référence à rien (incluant par exemple les données de type virgule flottante ou float, les données de type entier ou integer, short ou long, les données de type booléen) sont facilement manipulées à l'aide d'instructions basiques ayant le même type que ces données. En effet, les instructions basiques peuvent être typées ou non typées. Lorsqu'elles sont typées, un type, entier ou référence par exemple, leur est affectée correspondant au type autorisé de leur opérande par exemple et autorisant donc uniquement la manipulation de données ayant le même type. En pratique c'est lors de la compilation de l'application que des vérifications sont menées quant à la compatibilité du type de l'instruction basique avec les données qui serviront d'opérande. Notons que certaines instructions basiques peuvent mettre en oeuvre à la fois des données de type entier et des données de type référence, par exemple l'instruction Java Card permettant de dépiler un entier de la pile d'opérandes et de le stocker dans l'attribut #i de l'objet dont la référence est à dépiler ensuite de la pile d'opérandes. Les attaques par confusion de type consistent alors pour l'attaquant à forcer ou « castel- » une donnée de type primitive, généralement un entier, sur une donnée de référence à un objet. Ainsi en manipulant la donnée de type entier, l'attaquant manipule également la donnée de référence. Il peut ainsi modifier la valeur d'adresse mémoire pour accéder à d'autres objets instanciés en mémoire ou d'autres applets, et du coup récupérer les valeurs d'attributs de ces autres objets ou accéder à des applications sécurisées. Les références étant affectées parmi un ensemble restreint de références, généralement les premières références jusqu'à un nombre maximal d'instanciations simultanées d'objets, il est aisé de déterminer la référence d'un autre objet. Cela est d'autant plus vrai que les plateformes Java Card sont généralement mises en oeuvre dans des dispositifs, type cartes à puce, dotés de peu de ressources et présentent donc un espace mémoire de travail confiné, partagé entre plusieurs applets exécutées par la même machine virtuelle JCVM. Ces attaques par confusion de type sont susceptibles d'affecter hautement la sécurité des systèmes informatiques car les attributs peuvent contenir des valeurs secrètes mais également les applications accédées peuvent être des applications de paiement, donc sensibles. Notamment, dans les plateformes Java Card, la machine virtuelle JCVM est activée tout le temps en mémoire non volatile ROM, signifiant que les instances d'objets sont permanentes. Une éventuelle attaque est donc susceptible d'engendrer des risques sur un plus long terme, contrairement notamment à la technologie Java classique où les instances d'objets sont détruites de la mémoire volatile RAM par exemple à l'extinction du dispositif. Les attaques par confusion de type sont possibles car certains environnements d'exécution informatiques ne vérifient pas le type des données entre une entrée (par exemple d'une méthode) et une sortie. Par exemple, la pile d'opérandes dans la plateforme Java Card a une largeur de deux octets permettant uniquement le stockage similaire des données codées sur deux octets qu'elles soient de type entier ou référence (la majorité des types de donnée selon Java Card, par exemple entier short, entier integer, référence, booléen, sont codées sur deux octets). En pratique, des applications malveillantes seules ou combinées à des injections de fautes peuvent être utilisées pour introduire des confusions de type dans les plateformes informatiques. Dans le cas de Java Card, certaines zones mémoires sont partagées par plusieurs applications Java. Ainsi, à l'aide de ces confusions de type, une application malveillante ou détournée par injection de faute peut accéder aux données sensibles d'une autre application. On distingue également les attaques par confusion directe de type et celles par confusion indirecte de type. L'attaque par confusion directe de type consiste à directement manipuler une donnée de type référence comme valeur d'entier (vice et versa), par exemple en affectant la valeur d'une première variable de type entier à une deuxième variable de type référence. Bien que les compilateurs ne permettent pas une telle affectation, l'établissement d'une séquence d'instructions illégales est toujours possible par des personnes mal intentionnées. L'attaque par confusion indirecte de type consiste, quant à elle, à manipuler une donnée de type référence comme valeur d'entier au travers de deux ou plus instances d'objets différents (vice et versa), l'un contenant un attribut de type référence et l'autre un attribut de type entier. Dans ce cas, la confusion de type naît du forçage d'un objet sur l'autre, permettant de manipuler l'attribut de type référence à l'aide de l'attribut de type entier de l'autre objet. Il existe donc des attaques de plusieurs sortes : uniquement applicatives (applications malveillantes seules) et par confusion directe de type, d'autres combinées (applications malveillantes et injection de fautes) et par confusion directe de type, d'autres uniquement applicatives et par confusion indirecte de type, et d'autres encore combinées et par confusion indirecte de type, elles-mêmes divisées en deux sous-ensembles : celles reposant sur une injection de faute sur les données (faute injectée pour modifier une valeur stockée), et celles sur une injection de faute sur le code (faute injectée pour force l'exécution du code ou des bytecodes à son avantage). Il existe quelques solutions protégeant les environnements d'exécution informatiques contre certaines de ces attaques. A titre d'exemple, la vérification d'instructions basiques (la plateforme Java Card inclut par exemple un vérifieur de bytecode Java Card) vérifie statiquement qu'un fichier binaire satisfait aux règles du langage de programmation et notamment aux règles de syntaxe et de type des données. Par exemple, la succession de deux instructions basiques manipulant la même donnée mais typées différemment sera interdite. Cette solution apparaît efficace contre les attaques uniquement applicatives, mais pas contre celles où une faute (postérieure à la vérification du bytecode) est injectée. Egalement, la publication « Mitigating Type Confusion on Java Card » (Dubreuil et al., International Journal of Secure Software Engineering, Vol. 4, No. 1, pp. 19-39, 2013) décrit une solution reposant sur la ségrégation des données de type référence et celles de type entier dans chaque pile d'opérandes utilisée par une méthode Java. Les données de type référence sont ajoutées et retirées par le haut de la pile, alors que les données de type entier le sont par le bas de la pile. Egalement, lorsqu'il ne reste qu'un opérande dans la pile (accessible aussi bien par le haut que le bas de la pile), l'attaque par confusion de type est toujours possible. Cette solution est efficace contre les attaques par confusion directe de type, mais reste inefficace contre celles par confusion indirecte de type. En outre, cette approche pose des difficultés pour le traitement des instructions basiques non typées (par exemple ou en Java), car dans ce cas il est impossible de savoir si la dernière donnée à utiliser doit être récupérée par le haut ou le bas de la pile. Enfin, la solution décrite dans « Java Card Combined Attacks with Localization-Agnostic Fault Injection » (J. Lancia, Proceedings of CARDIS '12, Vol. 7771 of LNCS, pp. 31-45, 2013) propose d'ajouter des informations d'intégrité sur les instances d'objet afin de détecter une modification de valeur d'attribut résultant d'une injection de faute. De fait, cette solution n'est pas efficace contre les autres attaques combinées (par injection de faute sur l'exécution du code) et contre celles qui sont uniquement applicatives. Le tableau en Figure 1 résume cette situation de l'état de l'art de ces quelques solutions à l'encontre des attaques par confusion de type (voir les trois premières colonnes : « Vérif. ByteCode », « Ségrégation dans OS » et « Information d'intégrité »). Les différentes solutions de l'état de l'art sont donc très partiellement efficaces contre l'ensemble des attaques connues par confusion de type. D'ailleurs, la combinaison de ces solutions ne permet pas de protéger de façon efficace un environnement d'exécution informatique contre l'ensemble des attaques connues. RESUME DE L'INVENTION La présente invention vise à pallier tout ou partie de ces inconvénients, notamment pour proposer des solutions de protection plus efficaces que celles connues, tendant notamment à une sécurisation hautement efficace contre l'ensemble des catégories connues d'attaques par confusion de type. A cet effet, un premier objet de l'invention concerne un procédé de sécurisation d'un environnement d'exécution informatique, en particulier Java Card, comprenant les étapes suivantes : affecter une référence d'origine à un objet d'un langage de programmation orienté objet lors de son instanciation dans l'environnement d'exécution ; et accéder audit objet instancié à l'aide de ladite référence d'origine affectée ; le procédé étant caractérisé en ce que toute référence à l'objet instancié est stockée dans une zone mémoire de l'environnement d'exécution informatique sous forme de référence d'origine transformée de sorte que des instructions basiques exécutées dans l'environnement d'exécution manipulent l'objet instancié à partir de la référence transformée. Le procédé selon l'invention permet d'améliorer la sécurisation des systèmes informatiques contre les attaques par confusion de type visant à accéder illégitimement à des objets instanciés car désormais leurs références ne peuvent plus être déduites aisément. Cette amélioration est obtenue par l'application d'une transformation sur la référence d'origine affectée à l'objet lors de son instanciation de sorte que seule la référence modifiée est stockée et manipulée par les instructions basiques (et donc par des personnes malveillantes). Cette approche de l'invention est d'autant plus efficace que l'affectation des références est classiquement linéaire ou incrémentale. En effet, dans ce cas, la transformation des références introduit une dispersion des valeurs d'adresse mémoire (les références affectées). Sans nécessairement permettre la détection d'une attaque par confusion de type (qui peut toutefois être obtenue lorsqu'une référence manipulée ne correspond pas à une référence d'origine dans un ensemble de valeurs possibles connu), l'invention permet d'éviter qu'un attaquant accède aisément à d'autres objets instanciés pour leur soutirer des données secrètes. Corrélativement, un deuxième aspect de l'invention concerne un système de sécurisation d'un environnement d'exécution informatique, en particulier Java Card, comprenant un module d'affectation configuré pour affecter une référence d'origine à un objet d'un langage de programmation orienté objet lors de son instanciation dans l'environnement d'exécution ; et un module d'accès pour accéder audit objet instancié à l'aide de ladite référence d'origine affectée ; caractérisé en ce que le système est configuré pour que toute référence à l'objet instancié soit stockée dans une zone mémoire de l'environnement d'exécution informatique sous forme de référence d'origine transformée de sorte que des instructions basiques exécutées dans l'environnement d'exécution manipulent l'objet instancié à partir de la référence transformée. Le système est donc adapté à la mise en oeuvre du procédé selon l'invention précédemment introduit, et peut être embarqué dans un dispositif tel une carte à microcircuit. L'invention a également pour objet un produit programme d'ordinateur comprenant des instructions adaptées à la mise en oeuvre de chacune des étapes du procédé décrit précédemment lorsque ledit programme est exécuté sur un ordinateur. Le système et le produit programme d'ordinateur présentent des avantages similaires à ce procédé. D'autres caractéristiques du procédé et du système selon des modes de réalisation sont décrites dans les revendications dépendantes. Par exemple, dans un mode de réalisation principal de l'invention, le procédé comprend la transformation de la référence d'origine en référence transformée en appliquant, à la référence d'origine, une fonction bijective de M vers N, où M représente l'ensemble des références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets (par exemple un nombre maximum d'objets instanciés dans l'environnement d'exécution, généralement 2m) et N représente un ensemble plus grand de références d'origine possibles compte tenu du codage binaire de celles-ci (par exemple le nombre de références possibles, soit 2n pour des références codées sur n bits, ou alors un ensemble optimisé par rapport à toutes ces références possibles). Cette configuration prévoit donc que la transformation conserve la même longueur binaire entre les deux références, seule étant introduite une dispersion des références transformées dans l'ensemble des valeurs de référence possibles (les références d'origine étant classiquement incrémentales ou prises dans l'ensemble plus petit M). Généralement les références sont codées sur deux octets. Bien entendu, des transformations modifiant la longueur binaire des références peuvent être envisagées dans le cadre de l'invention. En cas d'augmentation de la longueur binaire, un surcoût mémoire est à prévoir. La configuration ci-dessus permet donc de disperser l'ensemble des références utilisées par les instructions basiques ou bytecodes (références traditionnellement contigües) dans un ensemble de valeurs plus grand. Ainsi, un attaquant aura plus de difficulté à forcer une référence vue par les instructions basiques en une référence effectivement utilisée. Il en résulte une possible détection d'attaque dès lors qu'une référence incorrecte est utilisée. Selon un mode de réalisation particulier de l'invention, l'ensemble plus grand de références d'origine possibles est formé de l'ensemble des références inférieures à p (donc [0, ..., p-1]), où p est le plus grand nombre premier tel que p En outre, cette disposition confère une sécurité optimale du système car l'utilisation d'une référence transformée par une personne mal intentionnée doit nécessairement appartenir à l'ensemble f(M) pour tomber sur une référence d'origine valide. Selon un autre mode de réalisation particulier de l'invention, ladite fonction comprend des paramètres aléatoires propres au dispositif mettant en oeuvre le procédé. Les paramètres aléatoires sont notamment uniformément distribués. Cette disposition confère un degré supplémentaire de sécurité car notamment la fonction est secrète et, en cas de compromission d'une première carte, aucune information ne peut être déduite pour d'autres cartes. . Selon un encore autre mode de réalisation particulier de l'invention, ladite fonction est une fonction affine de type a.x+b mod p, où x est la référence d'origine, a et b sont deux paramètres aléatoires et p est le plus grand nombre premier tel que p Selon une caractéristique particulière dans un mode de réalisation, le paramètre aléatoire b est calculé comme suit : b = -a.R mod p, où R est une valeur aléatoirement choisie dans l'intervalle [2'41, p-1], où 2m définit le nombre maximal d'instanciations simultanées d'objets. Dans un autre mode de réalisation principal de l'invention, le procédé comprend une transformation inverse d'une référence manipulée par une instruction basique de sorte à obtenir une référence d'origine pour accéder à un objet instancié. Cette disposition précise le mécanisme par lequel l'environnement d'exécution, par exemple par le biais d'une machine virtuelle Java Card, accède concrètement aux objets instanciés tels que stockés en mémoire. Selon un mode de réalisation particulier de l'invention, le procédé comprend la détection d'une attaque lorsque la référence d'origine résultant de la transformation inverse n'appartient pas à un ensemble prédéfini de références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets. Habituellement, cet ensemble est constitué des M=2m premières références. Cette disposition permet la mise en place de contremesures visant à la protection du dispositif mettant en oeuvre le procédé, par exemple par l'effacement de données secrètes dans celui-ci ou par sa désactivation. En variante, pour éviter la transformation inverse, le procédé peut comprendre la vérification de si une référence manipulée par une instruction basique appartient à un ensemble prédéfini de références transformées, et la détection d'une attaque en cas de vérification négative. Cet ensemble prédéfini contient l'ensemble des références transformées possibles compte tenu du nombre maximal de références d'origine et de la fonction de transformation. Dans un autre mode de réalisation de l'invention, le procédé comprend le masquage d'une donnée de type entier avant d'être stockée, sous forme masquée, dans une zone mémoire de l'environnement d'exécution informatique. Ainsi les instructions basiques exécutées dans l'environnement d'exécution ne manipulent la donnée de type entier qu'à partir de la donnée masquée. Selon un mode de réalisation particulier de l'invention, le masquage est une opération OU EXCLUSIF ou XOR entre la donnée de type entier et f(0), où f(0) représente une valeur à l'origine d'une fonction mise en oeuvre pour la transformation de la référence d'origine en référence transformée. Cette configuration réalise ainsi un mécanisme d'offuscation des paramètres secrets de la fonction utilisée pour transformer les références, en empêchant que les données de type entier soient utilisées pour découvrir ces paramètres. Cette configuration permet en outre, pour des instructions basiques non typées, type ifeq et ifne dans Java, dont la comparaison avec des données manipulées se résume à une comparaison avec 0, d'uniquement comparer les données manipulées avec f(0) indépendamment du typage effectif de ces données. On s'affranchit ainsi d'effectuer le démasquage et la transformation inverse. De plus, l'utilisation d'un masquage de type XOR présente l'avantage que l'opération de démasquage consiste au même masquage, et donc ne requiert pas plus de ressources de traitement. Selon un autre mode de réalisation particulier de l'invention, lors de l'exécution d'une instruction basique manipulant la donnée masquée, la donnée masquée est démasquée pour permettre une opération sur la donnée de type entier. Ainsi les opérations sont réalisées sans erreur due au masquage. Bien entendu, on comprendra qu'avant stockage d'une valeur résultat de l'opération, cette valeur est à nouveau masquée. Dans un autre mode de réalisation de l'invention, le procédé est mis en oeuvre sur un dispositif conforme à la norme Java Card, par exemple une carte à microprocesseur. Il s'agit d'un domaine technique largement soumis à des attaques par confusion de type. La présente invention est donc particulièrement adaptée à ce domaine. Un troisième objet de l'invention concerne un dispositif électronique sécurisé, par exemple une carte à microcircuit ou carte à puce, embarquant un environnement d'exécution Java Card (Java Card Runtime Environment) et un système de sécurisation comme décrit ci-dessus. Un tel dispositif est donc efficacement sécurisé contre des attaques par confusion de type. BREVE DESCRIPTION DES FIGURES D'autres particularités et avantages de l'invention apparaîtront encore dans la description ci-après, illustrée par les dessins ci-joints, dans lesquels : - La Figure 1 dresse un tableau comparatif de la sécurisation contre les attaques par confusion de type, procurée par trois techniques connues et par les deux modes de réalisation de l'invention décrits à titre principaux ; - La Figure 2 illustre une architecture mémoire mise en oeuvre dans une plateforme JavaCard ; - La Figure 3 illustre, sous forme de logigramme, les principales étapes d'un mode de réalisation de l'invention ; et - La Figure 4 illustre, sous forme de logigramme, les principales étapes d'un autre mode de réalisation de l'invention. DESCRIPTION DETAILLEE DE L'INVENTION La présente invention concerne la sécurisation d'environnements d'exécution informatiques, par exemple des dispositifs électroniques portatifs et sécurisés dotés de peu de ressources, tels des cartes à puce. La technologie Java Card est largement répandue dans ces dispositifs. La description ci-après fait référence au contexte des plateformes Java Card. L'invention peut également s'appliquer à une machine virtuelle Java dans un ordinateur. Les plateformes Java Card mettent en oeuvre un environnement d'exécution Java Card (ou JCRE) responsable de la gestion des ressources de la carte à puce, notamment des mémoires, des communications réseaux et de l'exécution et la sécurité des applets. Il comprend une machine virtuelle (JCVM) instanciée pour chaque application Java Card, en charge d'exécuter le bytecode Java Card de l'application. Ainsi, le JCRE exécute les méthodes définies dans l'application Java Card et gère les différentes instances d'objets sur la plateforme. Lors que la machine virtuelle Java Card exécute une application, elle a besoin de mémoire pour stocker un grand nombre d'informations, incluant les instructions basiques ou bytecodes Java, les objets instanciés à partir de classes, les paramètres des méthodes exécutées, les valeurs retournées par ces méthodes, les valeurs locales de ces méthodes, et des résultats intermédiaires de calcul. La figure 2 illustre quatre zones mémoire du JCRE qui contiennent les données manipulées par les instructions basiques ou bytecodes Java de l'application Java Card. Chaque fois qu'une instance de classe ou d'objet est créée au cours de l'exécution de l'application Java Card, de la mémoire persistante ou réinscriptible (EEPROM/Flash) est allouée dans la zone mémoire référencée OIA (pour Object Instance Area) afin de mémoriser cette instance d'objet (incluant des données d'instance et des attributs). Pour pouvoir retrouver cet objet dans la zone mémoire OIA, une valeur d'adresse mémoire ou « référence » lui est attribuée et affectée. Cette référence, sur deux octets généralement, est incrémentée pour chaque nouvel objet instancié. La zone mémoire OIA est commune à l'ensemble des instances créées lors de l'exécution de toutes les applications Java Card présentes sur la carte. C'est cette zone mémoire qui constitue la vulnérabilité principale des plateformes Java Card aux attaques par confusion de type. Deux autres zones mémoires appartiennent à une zone mémoire principale dite « trame Java » (Java Stack) créée, en mémoire vive (RAM), pour chaque exécution d'une méthode Java dans l'application Java Card. La Java Stack comprend ainsi une pile d'opérandes (OS pour Operand Stack) où les opérandes et paramètres des instructions basiques sont poussés ou dépilés, et une table de variables locales (LV pour Local Variables) contenant les paramètres et variables locales de la méthode en cours d'exécution. Enfin, une zone mémoire BC en mémoire morte ROM contient le bytecode de l'application Java et par voie de conséquence des valeurs constantes définies dedans et utilisées par certaines instructions basiques. Ces valeurs constantes peuvent uniquement être poussées dans la pile d'opérandes OS. Cette zone mémoire n'a pas besoin d'être réinscriptible car les valeurs constantes n'ont pas vocation à être modifiées. L'architecture représentée sur la Figure 2 montre que la pile d'opérandes OS joue un rôle central : elle reçoit les données des autres zones mémoires afin de réaliser des opérations conformément aux instructions basiques exécutées, puis ses données sont dépilées pour être stockées soit dans la table LV (s'il s'agit par exemple d'une nouvelle valeur de variable locale) soit dans la zone OIA (s'il s'agit par exemple de nouveaux attributs d'un objet instancié). On s'intéresse en particulier aux instructions basiques de lecture ou écriture sur ces zones mémoires. Par exemple, le bytecode correspondant à est une instruction basique typée « short » (indiqué par le préfixe « s ») en ce que ses opérandes ou paramètres sont de type short. Cette instruction basique charge la variable locale de type short stockée dans l'entrée #3 de la table LV sur le sommet de la pile d'opérandes OS. Symétriquement dépile la valeur de type short située au sommet de la pile d'opérandes OS pour la stocker dans l'entrée #2 de la table LV. Les instructions et permettent les mêmes opérations sur, cependant, des données de type référence à un objet (le préfixe « a » faisant référence à une valeur d'adresse mémoire). Dans la norme Java Card Platform, les zones mémoires OS, LV et OIA où transitent les données manipulées par les instructions basiques stockent ces données en perdant tout information du type de celles-ci, car seule une largeur de deux octets est prévue pour stocker uniquement chaque valeur de ces données. C'est la raison pour laquelle la confusion malicieuse de type est possible. Dans l'attaque par confusion directe de type, la donnée de type référence est directement manipulée comme valeur d'entier. Par exemple une application malicieuse peut être conçue pour réaliser une séquence illégale d'instructions basiques, par exemple puis pour charger une valeur d'entier initialement dans la table LV (dans l'entrée #3) en une donnée de type référence dans l'entrée #2 de la table LV, en transitant par la pile d'opérandes OS. Ainsi en fixant une valeur souhaitée à l'entier stocké dans l'entrée #3 de LV, l'attaquant configure la référence définie dans l'entrée #2 de LV, référence permettant par exemple d'accéder à un nouvel objet instancié. Dans un autre exemple, une faute est volontairement injectée lors de l'exécution des instructions basiques de l'application Java Card. Par exemple, supposons que l'instruction est sur le point d'être exécutée avec un paramètre égal à Ox2B. Si la personne mal intentionnée injecte une faute pour modifier l'instruction en instruction qui ne fait rien et n'utilise aucun paramètre, alors le paramètre Ox2B est vu par la machine virtuelle JCVM comme le prochain bytecode à exécuter, correspondant à l'instruction basique . Il en résulte que la valeur entière de sommet de pile OS qui devait être manipulée par l'instruction basique se retrouve stockée dans la table LV comme référence. Dans l'attaque par confusion indirecte de type, la donnée de type référence est manipulée comme valeur d'entier au travers de deux ou plus instances d'objets différents, l'un contenant un attribut de type référence et l'autre un attribut de type entier. Par exemple, une classe 'C' d'objets contient un attribut 'att' de type référence : public class C { reference att }. Une personne mal intentionnée peut prévoir une autre classe 'B' d'objets contenant un attribut 'val' de type entier (short) : public class B { short val }. En créant une instance de l'objet B : B b = new B(); puis en « castant » (i.e. forçant) l'objet instancié de type B sur un objet de type C : C c = b; la personne mal intentionnée peut directement manipuler la donnée 'att' de type référence de l'objet c en modifiant la donnée 'val' de type entier de l'objet b' car dans cette configuration c.att = b.val. Grâce au « cast », le même objet en mémoire OIA est accessible à la fois comme objet c de type C et comme objet b de type B. Ce type d'attaque peut être réalisé à l'aide d'une application malveillante (modifiée par l'attaquant) ou par l'injection d'erreurs dans l'exécution de l'application Java Card de sorte à exécuter l'opération « C c=b; ». Pour contrer l'ensemble de ces attaques possibles par confusion de type entre notamment le type entier et le type référence, un procédé de sécurisation selon l'invention prévoit que toute référence à l'objet instancié est stockée dans une zone mémoire de l'environnement d'exécution informatique sous forme de référence d'origine transformée de sorte que des instructions basiques exécutées dans l'environnement d'exécution manipulent l'objet instancié à partir de la référence transformée. En d'autres termes, une transformation est appliquée à la référence affectée avant son stockage en mémoire. D'éventuelles personnes malintentionnées doivent donc être capables de déduire les valeurs transformées possibles pour pouvoir effectivement manipuler des objets instanciés. Le choix de transformations appropriées permet de disperser les références affectées possibles à l'intérieur d'un ensemble bien plus vaste, éventuellement de façon aléatoire. La probabilité pour qu'une personne malintentionnée puisse trouver accidentellement une référence modifiée correspondant effectivement à une référence d'origine affectée peut être donc faible, assurant une grande sécurité à l'environnement d'exécution contre les attaques par confusion de type. La Figure 3 illustre les principales étapes d'un procédé selon un mode de réalisation de l'invention. Une première étape E30 consiste à générer une fonction f inversible, de préférence aléatoire, propre au dispositif hébergeant l'environnement d'exécution, typiquement une carte à puce conforme à Java Card, puis à la mémoriser dans la machine virtuelle JCVM en mémoire ROM. Par exemple, f est une fonction bijective de M vers N. M représente l'ensemble des références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets, par exemple un nombre maximum d'objets instanciés dans l'environnement d'exécution, généralement 2m. En pratique on peut définir 1023 objets maximum, soit m=10 (la référence 0 étant interdite). N représente un ensemble plus grand de références d'origine possibles compte tenu du codage binaire de celles-ci, par exemple le nombre de références possibles, soit 2n pour des références codées sur n bits, ou alors un ensemble optimisé par rapport à toutes ces références possibles. En particulier, l'ensemble plus grand de références d'origine possibles est formé de l'ensemble des références inférieures à p (l'ensemble [0,...,p1]), où p est le plus grand nombre premier tel que p A noter que les paramètres a et b, et donc la fonction f, peuvent être définis lors d'une phase de personnalisation de la carte à puce embarquant l'invention. Ces paramètres sont générés par un dispositif de personnalisation puis écrits en mémoire ROM de la carte à puce à l'aide d'une commande de type ADPU (Application Protocol Data Unit). En variante, ces paramètres sont générés ou initialisés lors du chargement de la première applet dans la machine virtuelle JCVM de la carte ou lors du premier démarrage de la machine virtuelle JCVM. Dans encore une autre variante, les paramètres sont générés par la carte à puce elle-même, avec ou sans machine virtuelle JCVM (par exemple par le BIOS de la carte). Puis, l'étape E32 est effectuée à chaque instanciation d'un nouvel objet. Cet étape consiste, pour la machine virtuelle Java Card JCVM, à générer une nouvelle référence pour cet objet, en utilisant la fonction new(). Puis à l'étape E34, la référence obtenue X est transformée par la machine virtuelle JCVM en une référence transformée Y=f(X) en utilisant la fonction f ci-dessus. C'est cette référence transformée qui est stockée dans les zones mémoires OS, LV et OIA lorsqu'il s'agit de faire référence à un objet instancié. L'exécution de l'application Java est donc amenée, lorsqu'il s'agit d'accéder à ces objets instanciés, d'utiliser des instructions basiques manipulant la référence transformée Y plutôt que la référence d'origine X comme dans les solutions connues à ce jour. A l'étape E36, l'environnement d'exécution JCRE détecte l'exécution, par JCVM, d'une instruction basique qui souhaite accéder à l'objet désigné par la référence 25 Y. A ce stade, l'environnement d'exécution JCRE peut vérifier (étape E38) si la référence Y manipulée appartient à un ensemble prédéfini de références transformées, et détecter (étape E40) une attaque en cas de vérification négative. L'ensemble prédéfini des références transformées peut être mémorisé dans la carte. 30 Dans ce cas, des actions de sécurité peuvent être entreprises, comme par exemple désactiver la carte à puce. Par exemple si un attaquant teste la référence « 1 » alors que la fonction f ne peut pas retourner une telle référence partant des 1024 références d'origine possible, l'attaque est détectée. Si en revanche la vérification E38 est positive, la machine virtuelle JCVM peut calculer la transformation inverse de Y pour obtenir X=f1(Y)=(Y-b).a-1 mod p, de sorte à obtenir la référence d'origine et accéder à l'objet instancié (étape E42). Une variante à ce procédé est illustrée sur la Figure 4, où les étapes E30 à E36 et E40 sont similaires à celles de la Figure 3. Dans cette variante, les étapes E38 et E42 sont remplacées par les étapes E38' et E42' qui s'avèrent plus efficaces en terme de consommation mémoire (souvent limitée dans les cartes). En effet, ces étapes ne requièrent pas le stockage de toutes les références transformées possibles. En détails, à l'étape E38', on calcule X=ti (Y)=(Y-b).a-1 mod p, de sorte à obtenir la référence d'origine et on détecte une éventuelle attaque à ce stade, c'est-à- dire après la transformation inverse. Deux réalisations de la détection peuvent être envisagées. Dans une première forme de réalisation, la détection d'une attaque a lieu lorsque la référence d'origine résultant de la transformation inverse n'appartient pas à un ensemble prédéfini de références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets. Dans l'exemple qui précède, l'ensemble prédéfini de références d'origine est l'intervalle [1...2m]. Si X E [1...2m], aucune attaque n'est détectée, et le procédé peut accéder à l'objet instancié à l'aide de la référence X obtenue. Dans une deuxième forme de réalisation plus efficace, la détection d'une attaque a lieu lorsque la référence d'origine résultant de la transformation inverse n'appartient pas à un ensemble de références d'origine déjà affectées à des objets instanciés. En d'autres termes, on vérifie que la référence X=f-1(Y) obtenue correspond à une référence d'origine existante dans la JCVM. Cette vérification peut consister à vérifier qu'il existe effectivement un objet instancié à l'adresse mémoire X=f-1(Y), en utilisant par exemple une fonction de lecture. Ainsi, si une personne malveillante utilise une référence transformée ne correspondant pas à une référence d'origine existante, une attaque est détectée. Dans ce mode de réalisation de l'invention basé sur une fonction aléatoire, puisque l'attaquant n'a pas connaissance des paramètres a et b, il a, en fixant au hasard une valeur d'entier pour forcer une référence, une probabilité théorique P=2m/(p-1) de tomber sur une référence transformée valide (c'est-à-dire correspondant à une référence d'origine possible, sans garantie d'ailleurs qu'à ce moment de l'exécution cette référence d'origine ait été effectivement affectée à un objet instancié). Pour n=16 (deux octets) et m=10 (1024 instances maximum) qui représentent des cas classiques, cette probabilité est inférieure à 2%, assurant une détection théorique de 98% des attaques par confusion de type (p=65 521). Afin de sécuriser les paramètres a et b contre d'éventuelles attaques visant à les découvrir (et ainsi connaître f), les inventeurs ont prévu le masquage d'une donnée de type entier manipulée par une instruction basique avant d'être stockée, sous forme masquée, dans une zone mémoire de l'environnement d'exécution informatique. De préférence il s'agit d'un masquage par booléen. Par exemple, le masquage est une opération OU EXCLUSIF ou XOR (noté ,0) entre la donnée de type entier et f(0). Il est à noter que f(0)=b pour la fonction affine donnée à titre d'illustration ci-dessus. Ainsi, chaque fois qu'une instruction basique souhaite manipuler une donnée de type entier stockée, celle-ci doit d'abord être démasquée (un nouveau masquage XOR f(0) permet de réaliser ce démasquage) avant d'être utilisée pour fournir un résultat qui sera, lui, à nouveau masqué. La configuration proposée ci-dessus reste compatible avec l'ensemble des instructions classiques Java. Pour les instructions typées entier, le démasquage sur les données manipulées suffit. Pour les instructions typées référence, la transformation inverse permet d'accéder avec sécurité aux objets instanciés. Enfin, pour les instructions non typées, le choix de f(0) comme masque Z permet de simplifier les opérations de traitement visant à évaluer les données manipulées. En effet, pour les instructions basiques et , l'environnement d'exécution a besoin de comparer X=(Y-b).a-1 mod p ou X= YOZà la valeur 0, selon que la donnée manipulée est de type référence ou entier. Dans ce cas où la question est de savoir si X=0, le choix d'un masque Z=f(0) permet en effet d'obtenir Y=a.O+b mod p = 00 Z, d'où il résulte que les instructions basiques et peuvent être exécutées en comparant uniquement les données avec Z=f(0) indépendamment de leur type. On notera que les performances de détection d'attaque (>98%) de ce mode de réalisation de l'invention requièrent une faible consommation mémoire en raison principalement du fait que seuls les paramètres a et b ainsi que le nombre premier p définissant la fonction affine (voire la valeur f(0) pour réduire les calculs) ont besoin d'être mémorisés. En outre, la contrepartie en temps de traitement reste raisonnable car la fonction affine ne coûte qu'une multiplication, une addition et une réduction modulaire sur des mots de n-bits. En définitive, il s'agit de quelques cycles d'horloge par évaluation de la fonction f. Les exemples qui précèdent ne sont que des modes de réalisation de l'invention qui ne s'y limite pas. Notamment, si la description qui précède s'appuie sur une fonction f bijective, l'invention s'applique également dans le cas d'une fonction f injective. REVENDICATIONS1. Procédé de sécurisation d'un environnement d'exécution informatique comprenant les étapes suivantes : affecter une référence d'origine à un objet d'un langage de programmation orienté objet lors de son instanciation dans l'environnement d'exécution ; et accéder audit objet instancié à l'aide de ladite référence d'origine affectée ; le procédé étant caractérisé en ce que toute référence à l'objet instancié est stockée dans une zone mémoire de l'environnement d'exécution informatique sous forme de référence d'origine transformée de sorte que des instructions basiques exécutées dans l'environnement d'exécution manipulent l'objet instancié à partir de la référence transformée. 2. Procédé de sécurisation selon la revendication 1, comprenant la transformation de la référence d'origine en référence transformée en appliquant, à la référence d'origine, une fonction bijective de M vers N, où M représente l'ensemble des références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets et N représente un ensemble des références d'origine possibles compte tenu du codage binaire de celles-ci. 3. Procédé de sécurisation selon la revendication 2, dans lequel l'ensemble plus grand de références d'origine possibles est formé de l'ensemble des références inférieures à p, où p est le plus grand nombre premier tel que p 4. Procédé de sécurisation selon la revendication 2 ou 3, dans lequel ladite fonction comprend des paramètres aléatoires propres au dispositif mettant en oeuvre le procédé. 5. Procédé de sécurisation selon l'une des revendications 2 à 4, dans lequel ladite fonction est une fonction affine de type a.x+b mod p, où x est la référence d'origine, a et b sont deux paramètres aléatoires et p est le plus grand nombre premier tel que p 6. Procédé de sécurisation selon la revendication 5, dans lequel le paramètre aléatoire b est calculé comme suit : b = -a.R mod p, où R est une valeur aléatoirement choisie dans l'intervalle [2'41, p-1], où 2m définit le nombre maximal d'instanciations simultanées d'objets. 7. Procédé de sécurisation selon l'une des revendications 1 à 6, comprenant une transformation inverse d'une référence manipulée par une instruction basique de sorte à obtenir une référence d'origine pour accéder à un objet instancié. 8. Procédé de sécurisation selon la revendication 5, comprenant la détection d'une attaque lorsque la référence d'origine résultant de la transformation inverse n'appartient pas à un ensemble de références d'origine déjà affectées à des objets instanciés. 9. Procédé de sécurisation selon l'une des revendications 1 à 6, comprenant la vérification de si une référence manipulée par une instruction basique appartient à un ensemble prédéfini de références transformées, et la détection d'une attaque en cas de vérification négative. 10. Procédé de sécurisation selon l'une des revendications 1 à 9, comprenant le masquage d'une donnée de type entier avant d'être stockée, sous forme masquée, dans une zone mémoire de l'environnement d'exécution informatique. 11. Procédé de sécurisation selon la revendication 10, dans lequel le masquage est une opération OU EXCLUSIF ou XOR entre la donnée de type entier et f(0), où f(0) représente une valeur à l'origine d'une fonction mise en oeuvre pour la transformation de la référence d'origine en référence transformée. 12. Procédé de sécurisation selon la revendication 10 ou 11, dans lequel lors de l'exécution d'une instruction basique manipulant la donnée masquée, la donnée masquée est démasquée pour permettre une opération sur la donnée de type entier. 13. Procédé de sécurisation selon l'une des revendications 1 à 9, mis en oeuvre sur un dispositif conforme à la norme Java Card. 14. Produit programme d'ordinateur comprenant des instructions adaptées à la mise en oeuvre de chacune des étapes du procédé selon l'une quelconque des revendications précédentes lorsque ledit programme est exécuté sur un ordinateur. 15. Système de sécurisation d'un environnement d'exécution informatique comprenant : un module d'affectation configuré pour affecter une référence d'origine à un objet d'un langage de programmation orienté objet lors de son instanciation dans l'environnement d'exécution ; et un module d'accès pour accéder audit objet instancié à l'aide de ladite référence d'origine affectée ;caractérisé en ce que le système est configuré pour que toute référence à l'objet instancié soit stockée dans une zone mémoire de l'environnement d'exécution informatique sous forme de référence d'origine transformée de sorte que des instructions basiques exécutées dans l'environnement d'exécution manipulent l'objet instancié à partir de la référence transformée. 16. Système de sécurisation selon la revendication 15, comprenant une module de transformation de référence configuré pour transformer la référence d'origine en référence transformée en appliquant, à la référence d'origine, une fonction bijective de M vers N, où M représente l'ensemble des références d'origine disponibles compte tenu d'un nombre maximal d'instanciations simultanées d'objets et N représente un ensemble plus grand de références d'origine possibles compte tenu du codage binaire de celles-ci, ledit ensemble plus grand de références d'origine possibles étant formé de l'ensemble des références inférieures à p, où p est le plus grand nombre premier tel que p 17. Système de sécurisation selon la revendication 16, dans lequel ladite fonction du module de transformation de référence est une fonction affine de type a.x+b mod p, où x est la référence d'origine, et a et b sont deux paramètres aléatoires. 18. Système de sécurisation selon la revendication 17, dans lequel le paramètre aléatoire b est calculé comme suit : b = -a.R mod p, où R est une valeur aléatoirement choisie dans l'intervalle [2'41, p-1], où 2m définit le nombre maximal d'instanciations simultanées d'objets. 19. Système de sécurisation selon l'une des revendications 15 à 18, comprenant un module de transformation configuré pour effectuer une transformation inverse d'une référence manipulée par une instruction basique de sorte à obtenir une référence d'origine pour accéder à un objet instancié ; et un module de vérification et de détection d'attaque configuré pour vérifier si la référence d'origine résultant de la transformation inverse appartient à un ensemble de références d'origine déjà affectées à des objets instanciés. 20. Système de sécurisation selon l'une des revendications 15 à 19, 30 comprenant un module de masquage configuré pour masquer une donnée de type entier avant qu'elle soit stockée, sous forme masquée, dans une zone mémoire de l'environnement d'exécution informatique, le masquage étant une opération OU EXCLUSIF ou XOR entre la donnée de type entier et f(0), où f(0) représente une valeur à l'origine d'une fonction mise en 35 oeuvre pour la transformation de la référence d'origine en référence transformée. 21. Dispositif électronique sécurisé embarquant un environnement d'exécution Java Card et un système de sécurisation selon l'une des revendications 15 à 20.