Sécurité
Besoin
- Fonctionnel
- cryptographie (confidentialité,
authenticité, intégrité)
- Audit : la trace des transactions doit être conservée
en cas de contestation d'une partie ou pour des statistiques commerciales
- Légalité : les transactions doivent être
conformes aux lois des pays impliqués (législation de vente,
restrictions cryptographiques)
- Technique
- Evolutivité (ouvertures à de nouvelles solutions
de paiement par exemple)
- Intéropérabilité entre les différents
prestataires de services commerciaux (boutiques, fournisseurs, banques...)
- Distribution : l'informatique d'aujourd'hui est dominée
par le réseau et adopte un modèle coopératif, plus
souple. Il implique cependant de nouvelles contraintes de sécurité
distribuée.
- Portabilité : les architectures logicielles sont aujourd'hui
dynamiques, et dépendent de moins en moins d'une l'architecture
matérielle. Une même architecture logicielle peut se déployer
sur différentes architectures matérielles (exploitant des
postes clients tels que PC, Mac ou NC, des serveurs divers ainsi que d'autres
plates-formes telles que les appareils portables) et les exploiter différemment
(exploitation de la puissance de traitement, exploitation des périphériques).
Cette capacité implique la mobilité du code et donc de nouvelles
contraintes de sécurité.
- Simplicité : les opérations techniques, et notamment
les opérations de sécurité doivent être transparentes
pour l'utilisateur, et non pas constituer une contrainte à l'accès
au service
Analyse
La sécurité peut être abordée sous différents
angles :
- la définition d'une architecture
matérielle/réseau (firewalls,
proxies, etc.). La compréhension des
problématiques réseau liées
à la sécurité est effectivement importante dans la mesure
où elles ont un impact sur les possibilités des applications
développées (un serveur proxy
peut fortement limiter les possibilités d'une application
par exemple, et il faut savoir comment intégrer une application dans
une telle architecture).
- l'utilisation de procédés cryptographiques
- l'utilisation des caractéristiques de sécurité d'un
langage : Cette dernière approche
est relativement nouvelle, et trouve un nouvel essort grâce à
Java.
- le paramétrage de l'OS
C'est au travers d'une approche par composants qu'il convient de considérer
les problématiques de sécurité, chaque composant pouvant
se situer dans un des domaines cités. Chacun de ces domaines ne suffit
à lui seul à proposer une véritable solution de sécurité,
et plus que cela, chacun se doit de fournir une interface avec les autres.
Conception
DP |
Description |
Session |
suite d'échanges entre deux objets... |
Proxy |
objet auquel on délègue l'accès à un autre
objet. |
Objet gardé |
objet encapsulé par un autre, l'objet englobant régissant
les opérations autorisées sur l'objet englobé. De
manière plus générale l'objet gardé est
généralement un objet encapsulant un objet garde et un
ou plusieurs objets dont l'accès est contrôlé par
le garde.
Le principe d'encaspulation des objets gardés permet de transporter
un objet avec ses règles d'accès. Ils permettent donc
de répondre aux problématiques où l'on doit fournir
l'accès à un objet sans connaître le contexte de
sécurité du demandeur (celui-ci est distant et ne veut
pas transmettre son contexte trop sensible par exemple). Dans ce cas,
les objets gardés permettent de déléguer le test
de sécurité au demandeur lui-même, en retournant
l'objet demandé encapsulé avec son garde. Tout accès
à l'objet demandé ne pourra se faire directement, et devra
forcément être soumis à l'approbation du garde. |
Objets constants |
Les objets constants (non mutables ou immutables) sont des objets
dont l'état n'est accessible qu'en lecture seule On peut voir les
objets constants comme un objet gardé n'autorisant que la lecture. |
Objets opaques / transparents |
objet dont le contenu n'est pas accessible par celui qui le manipule
(une clé par exemple). |
Implémentation
La sécurité au niveau implémentation concerne :
- les API de sécurité
disponibles (cryptographie, etc.)
- la sécurité inhérente au langage
et la plate-forme Java eux-mêmes
(accès mémoire, robustesse, etc.)
API
Java offre des API cryptographiques
ainsi que des moyens de s'interfacer avec des composants matériels (réseau
typiquement) tels que les proxies ou suites
cryptographiques via des API adéquates.
Les objectifs de Java en matière de sécurité
sont de :
- Maximiser la sécurité pour le code suspect
- Maximiser la souplesse de la configuration pour le code sûr,
besoin de plus en plus répandu en raison de l'émergence d'intranets
et extranets. Il existe une forte demande pour ce type de fonctionnalité
(souplesse de configuration sans trop de contraintes pour l'utilisateur) à
laquelle Java doit répondre. A défaut de satisfaire cette demande
par un standard, Java sera fragmenté car étendu de manière
par des éditeurs fournissant des solutions propriétaires, ou
à défaut, son succès sera remis en cause.
Java se donne les moyens de la sécurité qu'il propose au travers
de garanties de :
- authentification : vous savez d'où vient le code
- intégrité :
on vous garantit que le code n'a pas été modifié
- confidentialité : le transit a été
crypté
- contrôle d'accès : la sandbox ou les domaines
de protection ont protégé vos ressources locales.
Afin de permettre à tout éditeur de fournir une implémentation
d'un ou plusieurs de ces concepts de sécurité, à toute
classe de sécurité générique (engine class)
est associée une fabrique (factory) retournant les implémentations
paramétrées dans la plate-forme (on retrouve là le modèle
de SPI).
Tout fournisseur est effectivement susceptible de ne pas implémenter
un protocole demandé par une application (il pourra fournir une implémentation
de signature RSA/MD2 mais pas de RSA/MD5 par exemple). Il est donc possible
d'installer dans la plate-forme plusieurs implémentations des classes
de sécurité, avec un ordre de préférence. Pour un
algorithme donné, la première implémentation trouvée
dans cette liste de préférence sera utilisée. Il est également
possible pour une application de spécifier son fournisseur de prédilection
par programmation.
Les concepts implémentables par un fournisseur sont :
- les clés publiques et privées (génération DSA
ou RSA, mapping sur une clé abstraite)
- les condensés de message (MD2, MD5, SHA)
- les signatures (DSA + SHA, RSA + MD5...)
- les certificats (X.509)
et leurs listes de révocation (CRL)
- la base locale d'informations sur les clés et certificats
(permettant différentes implémentation du stockage, sur une
carte à puce, sur un Java Ring, par exemple)
- Paramètres d'algorithme
- Générateur de paramètres d'algorithme
- Générateur de nombres aléatoire
Sécurité Java |
Version |
1 |
Commentaire |
Domaine |
Paradigme |
Release |
1 |
2 |
Architecture |
Sandbox |
|
|
|
Bac à sable ou TCB (Trusted Computing Base) = Ligne
Maginot : tout ou rien : une fois franchie, la guerre est perdue. Un bug,
tout est perdu. Franchir la ligne maginot, attaquer là où
on ne s'y attend pas, attaquer d'une manière non prévue
par l'auteur du TCB : la guerre est perdue. |
|
Permission |
|
Par nature (fonction de la provenance du code) |
|
|
Cryptographie |
Implémentations |
|
JDK |
Pluggable |
API cryptographiques standardisées et donc pluggables et interopérables |
|
Identité |
|
Classe java. security. Identity |
Interface java. security. Principal |
|
Propriétés |
|
|
Non |
java. security. manager |
Gestionnaire de sécurité à utiliser par l'application |
|
|
Non |
java. class. path |
Liste de répertoires ou fichiers JAR d'où charger des
classes locales non privilégiées (non système) |
|
|
Non |
java. security. policy |
URL du fichier de politique de sécurité à utiliser
(=) ou ajouter (==) à la politique courante. Avec le JDK 1.2, il
est possible de l'exprimer facilement à l'aide de l'outil graphique
(AWT) %java_home%/bin/policytool.exe . |
Langage et plate-forme
Java possède divers atouts pour l'élaboration
d'une solution sûre. Parmi ceux-ci, beaucoup sont liés au principe
de la JVM. Il s'agit de :
- robustesse
- l'exécution dans un processus
(celui de la JVM) garantit généralement
un espace d'adressage mémoire limité en lecture et en écriture,
voire un jeu d'instructions limité. Il offre de plus une protection
contre les plantages de la machine (une erreur fatale plante le processus,
mais pas l'OS).
- contrôle d'accès
- le typage fort : Un objet ne peut être manipulé
qu'au travers de son interface. En interdisant les conversions (transtypage
ou cast) sauvage, Java garantit l'intégrité
de l'état (des données) d'un objet (moyennant un développement
vertueux, que des attributs privés par exemple). D'une manière
générale, l'accès aux données est contrôlé
par l'interface du type de ces données, à l'exception malheureuse
des classes internes (inner classes du langage
Java). Cette sécurité permet d'autoriser plusieurs flots
d'exécutions (code + threads) à
partager le même espace d'adressage, ce qui est plus performant
que d'exécuter plusieurs applications dans des espaces d'adressage
différents ou d'utiliser une zone d'échange commune.
- Modificateurs d'accès (
private
, protected
,
final
). Encore une fois, ceci permet à plusieurs applis
de coopérer dans le même espace d'adressage de manière
sécurisée. Réelles limitations, contrairement au
C++.
- Objets constants : Java offre diverses classes d'objets constants
(non modifiables ou immutables) tels que les chaînes de caractères
(
String
) ou les wrappers de types simples (Integer
,
Long
, Float
, etc.). Ceci permet de retourner
un objet en lecture seule (la modification d'une chaîne retournée
ne doit pas modifier la chaîne d'origine par exemple). On peut voir
les objets constants comme un objet gardé n'autorisant que la lecture.
- mémoire
- GC local et distribué
- pas d'arithmétique de pointeurs - Les références
sur des objets Java ne peuvent être déplacées.
- Références constantes (référence
final
sur un objet)
- Tableaux à limites contrôlées - Un tableau
est (presque) un objet, dont la lecture et la modification du contenu
sont contrôlés afin d'éviter les accès mémoires
illégaux.
- Pas de préprocesseur -
- Exceptions systématiquement
remontées, doivent être gérées (compilateur), ou
sont gérées par la JVM (stacktrace output).
Notes
- Il n'y a pas de sécurité absolue. Aucun système
n'est inviolable. La mise en place d'une politique de sécurité
vise simplement à offrir un niveau de sécurité financièrement
acceptable par rapport au coût de l'absence de sécurité.
- le corrolaire est donc que le coût de la mise en place d'une politique
de sécurité ne doit pas dépasser le coût induit
par la violation de cette sécurité (vol ou dégradation
de service ou d'informations, manque à gagner...). Mettre en place
une politique de sécurité consiste toujours en définitive
à définir quel niveau de risque est acceptable pour un système
donné. Plus vous avez à perdre, plus vous êtes prêt
à payer pour le préserver. La sécurité
implémentée dans la plate-forme Java se doit donc d'être
souple, et non rigide, afin de pouvoir s'adapter aux contraintes de chacun.
Elle ne doit pas (comme dans ses premières versions), imposer par
défaut une sécurité trop importante qui ne révélera
inutile, voire dommageable (en performance notamment) dans certains cas de
figure. Cependant, elle doit être capable d'offrir un niveau de sécurité
important lorsque cela est nécessaire.
- Trop de sécurité nuit à la sécurité
: plus les contraintes seront grandes pour les utilisateurs, plus les utilisateurs
seront incités à contourner cette infrastructure. Java
doit donc pouvoir offrir un grand niveau de sécurité tout en
s'efforçant de minimiser les contraintes pour l'utilisateur. Maximiser
la transparence des opérations de sécurité passe par
l'utilisation de procotoles relativement transparents (comme SOCKS,
le SSO), et par la possibilité de distinguer les rôles des différents
utilisateurs du système : administrateur (capable de définir
la politique de sécurité d'un poste, à distance par exemple)
ou utilisateur simple de la plate-forme Java.
- Plus un algorithme est connu, plus il est sûr : il est illusoire
de penser qu'une bonne implémentation d'un algorithme de sécurité
est une implémentation confidentielle. Au contraire, tout bon algorithme
de sécurité (et tout bon système en général)
est un algorithme connu de tous, dont chacun peut déceler les failles
et les corriger. Nombre d'implémentations d'algorithmes sont disponibles
en OSS.
- Un modèle de sécurité efficace est un modèle
en couches. La responsabilité de la sécurité doit
être l'affaire de différentes composantes, et non d'une seule
(le modèle de sandbox de Java 1.1 est donc un mauvait modèle,
corrigé dans Java 2). Chaque composante à son rôle dans
la politique de sécurité, et l'ensemble du système développe
une synergie (1+1=3) plus efficace. Chaque couche doit remplir son rôle
et ne pas croire aveuglément la couche supérieure (ce n'est
pas parce la porte de ma maison est fermée à clé que
je laisse la nourriture sur la table de la cuisine).
Limitations
- Aucune approche de sécurité (architecture, cryptographie,
langage, OS) n'est suffisante en elle-même. Chaque spécialiste
de ces domaines ne considère trop souvent les problématiques
de sécurité qu'au travers de son domaine.
- l'aspect distribué des applications - L'utilisation du réseau
augmente les risques d'attaquent par chevaux de Troie (Trojan horse)
et par personne interposée (man in the middle).
- les aspects dynamiques et d'extensibilité (édition
de liens dynamique comme les capacités croissantes d'extension dynamique
de la plate-forme) augmentent les risques d'attaquent par chevaux de Troie
(Trojan horse) et par personne interposée (man in the middle).
- le modèle de bac à sable (sandbox) ou TCB
(Trusted Computing Base) est un modèle "tout ou rien"
n'offrant qu'un garde unique (gatekeeper). Des approches plus sûres
exploitent plusieurs gardes indépendants, où la faille d'un
garde ne remet pas en cause la sécurité du système dans
son ensemble. Ce modèle a été remis en cause depuis Java
2 [J2SE 1.2] avec les permissions.
- l'option visant à fournir une sécurité par le langage
et/ou la plate-forme implique que cette sécurité disparaît
dès que l'on quitte ce langage et/ou cette plate-forme. Or une application
Java doit pouvoir offrir une sécurité à des systèmes
non Java, récents ou anciens. La solution d'encapsulation n'est pas
toujours suffisante.
- le modèle objet masque l'implémentation derrière
une interface, autorisant ainsi le remplacement d'une implémentation
par une autre sans que le client n'en soit conscient. Un code hostile peut
ainsi être accédé à distance ou téléchargé.
De la même manière, l'utilisation de noms symboliques (services
d'annuaires tels que DNS ou autres) permet de remplacer
une implémentation par une autre et donc de redéfinir des services
de confiance.
- la redondance de divers mécanismes de sécurité
implémentés dans la plate-forme Java alors qu'ils sont parfois
offerts par les couches sous-jacentes (OS, matériel, réseau,
cryptographie des communications). Ceci peut nuire à la performance.
- des implémentations incorrectes, propriétaires ou incomplètes
de la plate-forme Java (dans certains anciens navigateurs
Web par exemple) contenant des bugs connus ou inconnus représentant
des failles de sécurité ou représentant des solutions
propriétaires de sécurité moins interopérables
et moins éprouvées que des standards. Cependant aujourd'hui
des extensions standards verticales existent pour le cryptage (JCE).
- le manque de standards de sécurité aboutis, implémentés
et largement diffusés (dans les navigateurs notamment), manque
comblé par des implémentations propriétaires (par Netscape,
Microsoft). Ces implémentations propriétaires de la plate-forme
Java sont aujourd'hui contournables grâce au Plugin
Java
- avant Java 1.2 :
- la complexité de la mise en oeuvre de mécanismes de sécurité
dans Java 1.1 (dérivation de SecurityManagers et de ClassLoaders).
Ceci est résolu depuis Java 2 [J2SE 1.2] par l'implémentation
de politiques de sécurité est simplifiée (plus besoin
de dériver des SecurityManagers ou ClassLoaders).
- l'immaturité de la plate-forme Java dans le domaine de la sécurité
en Java 1.1 : API limitée aux signatures
et condensés de messages (pas
de certificats), absence de permissions
fines pour du code téléchargé (logique "tout
ou rien" de la sandbox 1.1). Ce manque a été
comblé à nouveau par des implémentations propriétaires
(Netscape Capabilities API par exemple). Cependant Java 2 [J2SE
1.2] a introduit la JCA, définissant une
véritable architecture de sécurité supportant des
protocoles importants du monde de la sécurité (certificats
X.509, etc.).
- limitations du langage Java.
Glossaire
Identité
Personne ou organisme identifiable par sa clé
publique.
Dans Java 2, une identité est représentée par un java.security.Principal.
JEPI
Acronyme pour Joint Electronic Payment Initiative.
Le protocole JEPI défini en 1997 a l'avantage d'être indépendant
du protocole de paiement (il le négocie). Cependant, il ne spécifie
pas d'interface permettant à l'utilisateur d'exploiter de nouveaux protocoles
de paiement.
La première implémentation de JEPI est celle de CommerceNet,
en Java, mais n'exploite pas la possibilité de Java de télécharger
des nouveaux gestionnaires de protocoles (JAF ?) et du code (applications) en
général.
MAC
Acronyme pour Message Authentication Code, standard permettant de garantir
l'intégrité d'un message.
MOSS
Standard de sécurisation du courrier électronique conçu
pour dépasser les limites de PEM en supportant les
messages MIME.
Parce que MOSS est plus un framework qu'une spécification, et parce
qu'il dispose de nombreuses implémentations différentes, deux
correspondants MOSS peuvent avoir des difficultés à communiquer.
On pourra donc lui préférer S/MIME, clairement
défini.
RIPEMD-160
Acronyme pour RIPE Message Digest, algorithme de hâchage permettant
de générer des condensés de messages.
RIPEMD-160 ou SHA sont considérés comme plus
sûr que MD5, dans la mesure ou MD5 a été cassé (pour
des messages courts cependant). RSA elle-même ne recommande
plus l'utilisation de MD5.
RNG
Acronyme pour Random Number Generation, algorithme sécurisé
de génération de nombres aléatoires (non périodiques),
utilisés pour la génération de clés.
Java 2 ne fournit qu'une implémentation de nombres pseudo-aléatoires
(PRNG).
PRNG
Acronyme pour Pseudo Random Number Generation, algorithme sécurisé
de génération de nombres pseudo-aléatoires (pérodiques),
utilisé pour la génération de clés.
Java 2 inclut une implémentation de PRNG, via le générateur
java.security.SecureRandom.
SET
Acronyme pour Secure Electronic Transactions.
Protocole de commerce électronique situé au-dessus de SSL,
permettant les authentifications des clients porteurs de cartes de crédit,
des commerçants et des fournisseurs, l'intégrité
et la confidentialité des informations de paiement (du client vers le
commerçant) et de commande (du commerçant vers le fournisseur).
Comme SSL, SET exploite les certificats
X509.
SKIP
Acronyme pour Secure Key Internet Protocol.
S/WAN
Acronyme pour Secure Wide Area Network.
Permet d'intégrer de la sécurité pour les WAN au sein
de réseaux privées virtuels.
TIPEM
Acronyme pour Toolkit for Interoperable Privacy Ehanced Mail, librarie
de RSA permettant de développer des produits intégrant
S/MIME dans les applications de courrier électronique.
Le modèle de sécurité ActiveX
Comme pour les plugins, le modèle de sécurité ActiveX
:
- prétend limiter les possilité du code natif des ActiveX. Or
un ActiveX peut construire des pointeurs, etc.
- autorise tout par défaut (non signé). Java n'autorise rien
par défaut.
- repose entièrement sur le jugement de l'utilisateur. Lorsqu'une fenêtre
s'affiche en indiquant que Verisign garantit que Joe Schmoe est bien l'auteur
du programme téléchargé, on ne peut prendre de décision
raisonnable si l'on ne sais pas qui est Joe Schmoe.
- fonctionne en mode tout ou rien : si vous acceptez, le programme pourra
faire tout ce qu'il veut sur votre machine (définir un sécuritymanager
en Java 1.1 ou utiliser java2 permet de spécifier les actions autorisées).
Si vous refusez, il ne peut théoriquement rien faire. Mais il s'agit
de code natif, donc il peut tout faire (ou presque). Il exite également
une option permettant de *tout* accepter systématiqueemnt en provenance
d'une identité donnée.
- les plugins/activeX ne sont pas téléchargés à
chaque fois et restent sur votre poste
Evolution de OLE.
-> OLE inventé pour rendre Office plus flexible
--> Patch way of life
Sécurité Windows : non multi-utilsiateur non multisession, non
network... etc, C history ; patch way not designed for all this stuff.
La sécurité est dans l'OS Windows et non dans les composants
(sécurité au niveau du langage comme Java).
Voir