Vous êtes sur la page 1sur 55

Département : Génie Electrique & Informatique

Filière : Génie Télécommunications et Réseaux

Plateforme des méthodes de la sécurité


informatique

Rapport de projet de fin d’année

Réalisé par : Encadré par :


NABIL Salaheddine Pr. EL AKKAD Nabil
BOUSLYKHANE Abderrahmane

Année universitaire 2019-2020

1
Sommaire
Liste de figures ................................................................................................................................................................ 3
Introduction...................................................................................................................................................................... 4
La sécurité informatique .................................................................................................................................................. 5
Chapitre I : La signature numérique ................................................................................................................................ 7
1. Fonctionnement de la signature numérique : .................................................................................... 7
2. La signature numérique en java ........................................................................................................ 9
a) Envoi d'un message avec une signature numérique ...................................................................... 9
b) Vérification de la signature ......................................................................................................... 13
Chapitre II : FIREWALL ............................................................................................................................................... 16
1. FIREWALL .................................................................................................................................... 16
a) Pare-feu matériel et logiciel ........................................................................................................ 16
b) Fonctionnement général .............................................................................................................. 17
c) FIREWALL en java .................................................................................................................... 18
Chapitre III : Server Proxy............................................................................................................................................. 47
1. Les fonctionnalités d’un serveur PROXY ...................................................................................... 47
2. Server proxy en java ....................................................................................................................... 48
a) Implémentation............................................................................................................................ 48
b) Les classes ................................................................................................................................... 48
Chapitre IV : Systèmes de détection d’intrusion (IDS) ................................................................................................. 51
1. Les différents types d’IDS .............................................................................................................. 51
2. IDS à Modèles comportementaux :................................................................................................. 51
3. IDS réseau et IDS système .............................................................................................................. 52
4. Systèmes de détection d’intrusion (IDS) en java ............................................................................ 53
a) Port scannig ................................................................................................................................. 53
b) Explication du projet ................................................................................................................... 53
c) Affichage des résultats ................................................................................................................ 54
Conclusion ..................................................................................................................................................................... 55

2
Liste des figures

Figure 1 : schéma signature numérique ........................................................................................................................... 7


Figure 2 : cryptographie asymétrique. ............................................................................................................................. 8
Figure 3 : signature et vérification. .................................................................................................................................. 8
Figure 4 : informations du propriétaire de la clé publique............................................................................................. 11
Figure 5 : schématisation d’un FIREWALL. ................................................................................................................. 16
Figure 6 : comparaison entre FIRWALL matériel et logiciel. ....................................................................................... 17
Figure 7 : fonctionnement du serveur. ........................................................................................................................... 47
Figure 8: Networtk based IDS et Host based IDS ......................................................................................................... 52

3
Introduction
Ce document est un rapport du travail effectué pour la réalisation du projet
de fin d’année ayant comme sujet « Plateforme des méthodes de la sécurité
informatique ».
Le travail sur le projet a suivi des étapes bien précises et logiques commençant
par une introduction générale sur la sécurité informatique, puis plus précisément,
les méthodes :
Signature numérique, FIREWALL, server PROXY et IDS et leurs programmation
en langage java.

4
La sécurité informatique
La sécurité informatique est l’ensemble des moyens mis en œuvre pour réduire la
vulnérabilité d’un système contre les menaces accidentelles ou intentionnelles. Il
convient d'identifier les exigences fondamentales en sécurité informatique. Elles
caractérisent ce à quoi s'attendent les utilisateurs de systèmes informatiques en regard
de la sécurité :
1. disponibilité : demande que l'information sur le système soit disponible aux
personnes autorisées.
2. Confidentialité : demande que l'information sur le système ne puisse être lue que par
les personnes autorisées.
3. Intégrité : demande que l'information sur le système ne puisse être modifiée que par
les personnes autorisées.

Inutile de se préoccuper de sécurité sans avoir défini ce qui était à protéger : en


d’autres termes, toute organisation désireuse de protéger ses systèmes et ses réseaux doit
déterminer son périmètre de sécurité. Il est également important de définir contre qui et
quoi doit-on se protéger. il faut aussi élaborer une politique de sécurité, c’est à-dire
décider de ce qui est autorisé et de ce qui est interdit.

Ressources publiques, ressources privées


Les systèmes et les réseaux comportent des données et des programmes que nous
considérerons comme des ressources. Certaines ressources sont d’accès public, ainsi
certains serveurs web, d’autres sont privées pour une personne, comme une boîte à
lettres électronique, d’autres enfin sont privées pour un groupe de personnes, comme
l’annuaire téléphonique interne d’une entreprise. Ce caractère plus ou moins public
d’une ressource doit être traduit dans le système sous forme de droits d’accès.

Identifier et authentifier
Les personnes qui accèdent à une ressource non publique doivent être identifiées
; leur identité doit être authentifiée ; leurs droits d’accès doivent être vérifiés au regard
des habilitations qui leur ont été attribuées. À ces trois actions correspond un premier
domaine des techniques de sécurité : les méthodes d’authentification, de signature, de
vérification de l’intégrité des données et d’attribution de droits.
La sécurité des accès par le réseau à une ressource protégée n’est pas suffisamment
garantie par la seule identification de leurs auteurs. Sur un réseau local de type Ethernet
ou Wi-Fi où la circulation des données fonctionne selon le modèle de l’émission
radiophonique que tout le monde est censé pouvoir capter, il est possible de détourner
cette circulation. Si la transmission a lieu à travers l’Internet, les données circulent de
façon analogue à une carte postale, c’est-à-dire qu’au moins le facteur et la concierge y
ont accès. Dès lors que les données doivent être protégées, il faut faire appel aux
5
techniques d’un autre domaine de la sécurité informatique : le chiffrement.
Authentification et chiffrement sont indissociables : chiffrer sans authentifier ne protège
pas des usurpations d’identité (comme notamment l’attaque par interposition, dite en
anglais attaque de type Man in the middle), authentifier sans chiffrer laisse la porte
ouverte au vol de données.

Empêcher les intrusions


Ces deux méthodes de sécurité ne suffisent pas, il faut en outre se prémunir contre les
intrusions destinées à détruire ou corrompre les données, ou à en rendre l’accès
impossible. Les techniques classiques contre ce risque sont l’usage de pare-feu(fire-
walls) et le filtrage des communications réseaux, qui permettent de protéger la partie
privée d’un réseau dont les stations pourront communiquer avec internet sans en être
visible. La plupart des entreprises mettent en place des ordinateurs qu’elles souhaitent
rendre accessibles aux visiteurs extérieurs, tels que leur serveur web et leur relais de
messagerie. Entre le réseau privé et l’Internet, ces machines publiques seront placées sur
un segment du réseau ouvert aux accès en provenance de l’extérieur, mais relativement
isolé du réseau intérieur, afin qu’un visiteur étranger à l’entreprise ne puisse pas accéder
aux machines à usage strictement privé. Certains auteurs considèrent que ces techniques
de sécurité par remparts et pont-levis sont dignes du Moyen Âge de l’informatique ; ils
leur préfèrent les systèmes de détection d’intrusion (IDS), plus subtils, Cette innovation
a suscité une surenchère, qui proclame que si l’on a détecté une intrusion, autant la
stopper, et les IDS sont ainsi devenus des IPS (systèmes de prévention d’intrusion). Cela
dit, dans un paysage informatique ou les micro-ordinateurs et autre objets communicant
se multiplient rapidement et en grande quantité, il n’est pas réaliste de prétendre vérifier
la configuration de chacun, le filtrage et le pare-feu sont encore irremplaçables. Ainsi si
la détection d’intrusion est une mesure importante à mettre en place, son implémentation
efficace reste difficile.

Pour couper court à toutes ces querelles autour des qualités respectives de telle ou
telle méthode de sécurité, il suffit d’observer l’état actuel des menaces et des
vulnérabilités. Il y a encore une quinzaine d’années, le paramétrage de filtres sur le
routeur de sortie du réseau d’une entreprise vers l’Internet pouvait être considéré comme
une mesure de sécurité bien suffisante, puis il a fallu déployer des antivirus sur les postes
de travail. Aujourd’hui, une dizaine de nouvelles vulnérabilités apparaissent chaque
semaine et l’idée de pouvoir se prémunir de ce flux d’intrusions semble impossible. La
conception moderne de la protection des systèmes et des réseaux s’appuie sur les notions
de défense en profondeur et de réaction aux incidents, par opposition à la défense
frontale rigide, où l’on mise tout sur l’efficacité absolue d’un dispositif unique.

6
Chapitre I : La signature numérique
La signature numérique est une signature électronique renforcée partiellement ou
entièrement grâce à la cryptographie. Dans l’état actuel des technologies de
l’information (TI), il s’agit de la meilleure méthode de signature pour s’assurer de
l’intégrité et de l’origine d’un document électronique. Elle constitue un élément
supplémentaire prouvant l'origine, l'identité et l'état d'un document électronique, d'une
transaction ou d'un message et démontre le consentement éclairé du signataire.

Figure 1 : schéma signature numérique

1. Fonctionnement de la signature numérique :

La signature d'un document utilise à la fois la cryptographie asymétrique et les


fonctions de hachage. C'est en effet par l'association de ces deux techniques que nous
pouvons obtenir les 5 caractéristiques d'une signature (authentique, infalsifiable, non
réutilisable, inaltérable, irrévocable).

Cryptographie asymétrique :

Les concepts de signature numérique sont principalement basés sur la cryptographie


asymétrique. Cette technique permet de chiffrer avec un mot de passe et de déchiffrer avec
un autre, les deux étant indépendants et peut utiliser la clé privée pour chiffrer, la clé
publique servant à déchiffrer.
Par contre la cryptographie symétrique qui génère tout d'abord un couple de clés. Une
clé privée et une clé publique. Ces clés ont des propriétés particulières vis à vis des
algorithmes utilisés. En effet, un message chiffré avec une clé ne peut être déchiffré qu'avec
l'autre clé. Il s'agit de fonctions à sens unique.
Le message ainsi chiffré est lisible par toute personne disposant de la clé publique. Ceci
n'est pas très utile si l'on cherche la confidentialité. En revanche, seul l’expéditeur qui est
susceptible d'avoir chiffré le message et c'est la personne à avoir chiffré ce message
7
Figure 2 : cryptographie asymétrique.

Fonctions de hachage :

o Pour décrire les mécanismes permettant de s'assurer que des données n'ont pas été
modifiées : les fonctions de hachage.

o Une fonction de hachage est un procédé à sens unique permettant d'obtenir une suite
d'octets (une empreinte) caractérisant un ensemble de données. Pour tout ensemble de
données de départ, l'empreinte obtenue est toujours la même.

o Dans le cadre de la signature numérique, nous nous intéresseront tout particulièrement


aux fonctions de hachage cryptographiques. Celles-ci assurent qu'il est impossible de
créer un ensemble de données de départ donnant la même empreinte qu'un autre
ensemble.

o Nous pouvons donc utiliser ces fonctions pour nous assurer de l'intégrité d'un document.

Figure 3 : signature et vérification.

8
2. La signature numérique en java

a) Envoi d'un message avec une signature numérique

Techniquement parlant, une signature numérique est le hachage chiffré (résumé,


somme de contrôle) d'un message. Cela signifie que nous générons un hachage à partir
d'un message et le chiffrons avec une clé privée selon un algorithme choisi.
Par la suite on aura 3 éléments que l’émetteur doit envoyer :
• Le message,
• Le hachage chiffré (représentant la signature digitale),
• La clé publique pour le déchiffrement (sous forme de certificat numérique).
Donc commençant maintenant par la préparation de ces trois éléments :

Gestion des clés

Étant donné que la signature numérique utilise une clé privée et publique, nous utiliserons
respectivement les classes PrivateKey et PublicKey de l’architecture cryptographique du
java pour signer et vérifier un message.
Private Key (clé privée) : Utilisée seulement par l’émetteur pour chiffrer le résultat de
hachage de son message ce qui donne la signature numérique.
Public Key (clé public) : Disponible pour le publique. Utilisée pour déchiffrer le
hachage pour vérifier s’il correspond au hachage réel.
La question qui se repose est la suivante : Comment savons-nous que la clé publique
provient vraiment de la bonne entité ?
C’est ça ce que l’utilisation de certificats numériques viennent de résoudre.
Un certificat est un document qui associe une identité à une clé publique donnée. Les
certificats sont signés par une entité tierce appelée autorité de certification (CA). Un
certificat numérique contient une clé publique et est lui-même signé par une autre entité.
La signature de cette entité peut elle-même être vérifiée par une autre entité et ainsi de
suite. Nous finissons par avoir ce que nous appelons une chaîne de certificats. Chaque
entité supérieure certifie la clé publique de l'entité suivante. L'entité la plus élevée est
auto-signée, ce qui signifie que sa clé publique est signée par sa propre clé privée.
Le X.509 est le format de certificat le plus utilisé et il est livré au format binaire (DER)
ou au format texte (PEM).

9
Obtenir une paire de clés
Pour créer une paire de clés privée et publique, nous utiliserons l'outil de clé Java.
Générons une paire de clés à l'aide de la commande genkeypair :
Dans le CMD tapez:
keytool -genkeypair -alias senderKeyPair -keyalg RSA -keysize 2048 -validity 365
storetype PKCS12 -keystore sender_keystore.p12 -storepass password123
Cela crée une clé privée et sa clé publique correspondante pour nous. La clé publique
est encapsulée dans un certificat auto-signé X.509 qui est à son tour encapsulé dans une
chaîne de certificats à élément unique. Nous stockons la chaîne de certificats et la clé
privée dans le fichier Keystore sender_keystore. p12.
En outre, il faut se souvenir du mot de passe et de l'alias, car ils seront utilisés lors du
chargement du fichier Keystore.

Maintenant que nous avons obtenu une paire de clés ; une clé privée qu’on va utiliser
pour le chiffrement, et autre publique qu’on peut partager.

Publication de la clé publique


Pour cela nous allons utiliser un certificat auto-signé qu’on peut exporter à partir du
fichier

10
Keystore précédemment créé (sender_keystore.p12) . Nous pouvons le faire avec la
commande exportcert :
Dans le CMD tapez la commande suivante :
keytool -exportcert -alias senderKeyPair -storetype PKCS12 -keystore
sender_keystore.p12 -file sender_certificate.cer -rfc -storepass password123
Par cela on reçoit le certificat numérique qui associe l’identité du propriétaire de la clé
publique, représenter comme au-dessous :

Figure 4 : informations du propriétaire de la clé publique.

Maintenant qu’on a la clé publique et le message à envoyer, il nous reste que la signature
pour terminer les trois éléments principaux dont on a parlé qu’ils sont nécessaires pour
l’envoi.

Chargement de la clé privée pour la signature


Pour signer un message, nous avons besoin d'une instance de PrivateKey . En utilisant
l’API KeyStore et le fichier Keystore précédent, sender_keystore.p12, nous pouvons
obtenir un objet PrivateKey :
/**

* Creating an instance for private key

*/

11
String storePass = "password123";

KeyStore keyStore = KeyStore.getInstance("PKCS12");

keyStore.load(new FileInputStream("sender_keystore.p12"), storePass.toCharArra


y());

PrivateKey privateKey =
(PrivateKey) keyStore.getKey("senderKeyPair", storePass.toCharArray());

Maintenant que nous avons une instance PrivateKey du côté expéditeur et une instance
de PublicKey , nous pouvons commencer le processus de signature.
Comme nous l'avons vu, la signature numérique est basée sur le hachage et le
chiffrement. Habituellement, nous utilisons la classe MessageDigest avec SHA ou
MD5 pour le hachage et la classe Cipher pour le chiffrement.
Génération d'un hachage de message

Un message peut être une chaîne, un fichier ou toute autre donnée. Prenons donc le
contenu d'un simple fichier “message.txt” :
/**

* Hashing our message so we get our digest

*/ byte[] messageBytes = Files.readAllBytes(Paths.get("message.txt"));

Maintenant, en utilisant MessageDigest, utilisons la méthode digest pour générer un


hachage :
MessageDigest md = MessageDigest.getInstance("SHA-256") ; byte[]

messageHash = md.digest(messageBytes);

Ici, nous avons utilisé l'algorithme SHA-256, qui est le plus couramment utilisé. D'autres
alternatives sont MD5, SHA-384 et SHA-512.

Chiffrement du hachage généré

Pour crypter un message, nous avons besoin d'un algorithme et d'une clé privée. Ici, nous
allons utiliser l'algorithme RSA.
Créons une instance de chiffrement et initialisons-la pour le chiffrement. Ensuite, nous
appellerons la méthode doFinal() pour crypter le message haché précédemment :

12
/**

* encrypting the digest we got with our private key so we create the digital

signature

*/

Cipher cipher = Cipher.getInstance("RSA");


cipher.init(Cipher.ENCRYPT_MODE, privateKey);

byte[] digitalSignature = cipher.doFinal(messageHash);

La signature peut être enregistrée dans un fichier pour être envoyée ultérieurement :
Files.write(Paths.get("digital_signature"), digitalSignature);

À ce stade, le message, la signature numérique, la clé publique et l'algorithme sont tous


envoyés, et le récepteur peut utiliser ces informations pour vérifier l'intégrité du
message.

b) Vérification de la signature

Chargement d’une clé publique pour vérification

Ayant accès à la clé publique, un récepteur peut la charger dans son magasin de clés à
l'aide de la commande importcert :
keytool -importcert -alias receiverKeyPair -storetype PKCS12 \ -
keystore receiver_keystore.p12 -file \ sender_certificate.cer -rfc -storepass password123

Et en utilisant l’API KeyStore comme précédemment, nous pouvons obtenir une instance
PublicKey :
String storePass = "password123";
13
KeyStore keyStore = KeyStore.getInstance("PKCS12");

keyStore.load(new FileInputStream("receiver_keystore.p12"), storePass.toCharAr


ray());

// remember always your alias wich is in our case: receiverKeyPair

Certificate certificate = keyStore.getCertificate("receiverKeyPair");


PublicKey publicKey = certificate.getPublicKey();

Maintenant que nous avons une instance PrivateKey du côté expéditeur, nous pouvons
commencer le processus de vérification.

Vérification de la signature

Lorsque nous recevons un message, nous devons vérifier sa signature. Pour ce faire,
nous déchiffrons le hachage chiffré reçu et le comparons avec un hachage que nous
faisons du message reçu.
Lisons la signature numérique reçue :
/**

* read the received digital signature

*/ byte[] encryptedMessageHash =

Files.readAllBytes(Paths.get("digital_signatur

e"));

14
Pour le déchiffrement, nous créons une instance de chiffrement. Ensuite, nous appelons
la méthode doFinal :
/**

* We decrypt the digital signature to get the hashed message

*/

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, publicKey);

byte[] decryptedMessageHash = cipher.doFinal(encryptedMessageHash);

Ensuite, nous générons un nouveau hachage de message à partir du message reçu :


/**

* Now we generate new Hash from the received message

*/

byte[] messageBytes = Files.readAllBytes(Paths.get("message.txt"));

MessageDigest md = MessageDigest.getInstance("SHA-256");

byte[] newMessageHash = md.digest(messageBytes);


Et enfin, nous vérifions si le hachage de message nouvellement généré correspond à celui
déchiffré :

/**

* We compare between the two hashes

*/ boolean isCorrect = Arrays.equals(decryptedMessageHash, newMessageHash);

System.out.println("Result: \n" + isCorrect);

15
Chapitre II : FIREWALL

1. FIREWALL
Un firewall - littéralement "mur de feu" - est un logiciel et/ou un matériel permettant de
filtrer ce qui passe d'un réseau à un autre. C’est un mur virtuel qui bloque tout ce qui tente
d'entrer avec l'intention de nuire dans une machine ou un réseau. Il établit une barrière de
protection contre les intrusions et les contaminations venant de l’extérieur.
On s'en sert pour sécuriser les réseaux et les ordinateurs, c'est-à-dire contrôler les
accès et les flux de données et bloquer ce qui est interdit.
Typiquement, il va :
• Autoriser les ordinateurs du réseau local à se connecter à internet.
• Bloquer les tentatives de connexion d'internet vers les ordinateurs du réseau
local.

Figure 5 : schématisation d’un FIREWALL.


a) Pare-feu matériel et logiciel
Pare-feu matériel :
Ce sont les premières lignes de défense car ils sont principalement configurées
sur des boîtes réseau (modems / routeurs) contenant du matériel et des logiciels
personnalisés. Il surveille chaque paquet qui atteint votre réseau en vérifiant sa source
et sa destination et son en-tête si on peut faire confiance. Uniquement lorsque le paquet
est vérifié, il est permis de passer par le pare-feu matériel et dirigé vers la machine
destinataire. Selon le paramètre du pare-feu actuel, il filtre le trafic en conséquence.
Les pare-feu matériels sont bons pour les propriétaires d'entreprises petites ou
moyennes, avec un petit réseau d'ordinateurs avec 5 PC ou plus. Ceux-ci deviennent
rentables car si vous choisissez d'acheter des licences de logiciels pour chaque machine,
disons 20 à 30 copies sur un abonnement annuel, cela vous coûtera beaucoup d'argent.

16
Pare-feu logiciel :
Un pare-feu logiciel est plus une machine individuelle lorsque le nombre
d'utilisateurs est relativement inférieur à une organisation. Cependant, dans les grandes
organisations, malgré une sécurité du pare-feu matériel, il est recommandé d'utiliser
également un pare-feu logiciel. C'est en grande partie parce qu'il peut y avoir des
utilisateurs / employés qui ont tendance à transporter et à travailler sur leurs systèmes
sur le réseau sécurisé des entreprises.
Dans ces cas, il est important de les protéger.
Un autre avantage majeur sur les pare-feu logiciels est qu'ils sont facilement évolutifs.
Les utilisateurs peuvent simplement télécharger des correctifs, des correctifs, des mises
à jour et des améliorations sur le site Web du fournisseur de pare-feu, ou dans la plupart
des cas, le fournisseur envoie ces améliorations via Internet.

Figure 6 : comparaison entre FIRWALL matériel et logiciel.

b) Fonctionnement général

Le Firewall a pour principale tâche de contrôler le trafic entre différentes zones de


confiance, en filtrant les flux de données qui y transitent. Généralement, les zones de
confiance incluent Internet (une zone dont la confiance est nulle) et au moins un réseau
interne (une zone dont la confiance est plus importante).
Le but est de fournir une connectivité contrôlée et maîtrisée entre des zones de différents
niveaux de confiance, grâce à l'application de la politique de sécurité et d'un modèle de
connexion basé sur le principe du moindre privilège.
Le filtrage se fait selon divers critères. Les plus courants sont :
• l'origine ou la destination des paquets (adresse IP, ports TCP ou UDP,
interface réseau, etc.) ;
• les options contenues dans les données (fragmentation, validité, etc.) ; • les
données elles-mêmes (taille, correspondance à un motif, etc.) ;
• les utilisateurs pour les plus récents.

17
Technologies utilisées :

Les pare-feu récents embarquent de plus en plus de fonctionnalités, parmi


lesquelles on peut citer :
• Filtrage sur adresses IP / protocole.
• Inspection stateful et applicative.
• Intelligence artificielle pour détecter le trafic anormal.
• Filtrage applicatif :
o HTTP (restriction des URL accessibles).
o Courriel .
o Logiciel antivirus, anti-logiciel malveillant.
• Traduction d'adresse réseau.
• Tunnels IPsec, PPTP, L2TP.
• Identification des connexions.
• Serveurs de protocoles de connexion (telnet, SSH), de protocoles de transfert
de fichier (SCP).
• Clients de protocoles de transfert de fichier (TFTP).
• Serveur Web pour offrir une interface de configuration agréable.
• Serveur mandataire (« proxy » en anglais).
• Système de détection d'intrusion (« IDS » en anglais).
• Système de prévention d'intrusion (« IPS » en anglais).

c) FIREWALL en java

Le présent programme consiste à créer multiple clients qui se connecte à un


serveur. Sur le serveur un Firewall est appliqué, le serveur peut mettre des règles pour
bloquer n’importe quelle adresse IP et peut aussi mettre des règles pour le filtrage des
messages.

Ce programme est construit en Java, il se compose de 6 classes expliquées ci-dessous :

18
fichier Server.java:
Ce fichier contient 3 classes :
• Class Server
Cette classe a pour but de lancer le serveur en localhost sur le port 7344 ;

Appel à l'interface graphique ServerWindow;

Envoi d'@IP et port du client vers l'interface graphique.

• Class ClientSession Constructeur


Initialisation de socket client ;

ClientSession(Socket sock) {

this.clientsocket = sock; temp =

clientsocket.getRemoteSocketAddress().toString();

Run()
Lecture des @IP interdite stockée sur 'block.txt' et remplissage de la liste noire déclarée
précédemment, si l'@IP du client et dispo sur la liste noire un message d'erreur sera affiché au
client.

• Class ServerWindowThread
Lance l’interface graphique ServerWindow
class ServerWindowThread extends Thread

{ public void

run()

ServerWindow sw = new ServerWindow();

}
Fichier ServerWindow.java:

Cette classe représente l’interface graphique coté serveur. Elle fonctionne en parallèle avec le
Thread du serveur ce qui garantit une interaction serveur-GUI ( graphic user interface) en temps
réel.

19
Données :
/*

* Class variables declaration

*/

static String confirmation=""; static


String print=""; static String
confirm=""; static Thread
t=Thread.currentThread();

Constructeur «ServerWindow» :
• S’occupe ici de l’appel de composants d’interface
• Définir une boucle infini tant que le serveur est en cours, en attendant les messages
définissant l’état d’interaction client-serveur pour les affichées sur l’interface.

public ServerWindow() {

20
// set background color to black

getContentPane().setBackground(new Color(0, 0, 0));

// call components initialization method

initComponents(); // set a position

this.setLocation(770, 0);

this.setVisible(true);

while(!t.isInterrupted())

if(confirm.equals(confirmation)==false)

jTextArea1.append(confirmation);

jTextArea2.append(print);

confirm=confirmation; print="";

Méthode «GetWelcomeMessage» :
Déclarée statique, appelée juste après le démarrage de serveur.
Prend en paramètre un tableau de taille 2 stockant l’@IP plus le port sur lesquels il marche.

public static void getWelcomeMessage(String args[])

confirmation="Welcome! This server is running on IP " + args[0] + "\nand port " + args[1] + "\nWaiting for Connection..\n";

Méthode «getConfirmation» :
Déclarée statique, appelée par le serveur dès qu’un nouveau client vient de se connecter .

Prend en paramètre un tableau contient une chaine de caractères indiquant si le client est bloqué
de rejoindre le serveur ou pas.

21
Exemples :
• 192.168.0.10 Blocked
Chargée aussi d’enregistrement de l’@ IP de client et la date de connexion sur le fichier
‘log.txt’.
public static void getConfirmation(String args[])

if(args[0].contains("Blocked")==false)

confirmation="Connection Established from IP " + args[0] + "\n";

print=args[0] + "\n";

else

confirmation="Connection from IP " + args[0] + "\n";

print=args[0] + "\n";

try

// Saving client’s IP address and connection time on log.txt File.

String filename= "log.txt";

FileWriter fw = new FileWriter(filename,true);

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd\tHH:mm:ss");

Calendar cal = Calendar.getInstance(); fw.write(args[0] + "\t\t" +

dateFormat.format(cal.getTime()) + "\n"); fw.close();

catch(IOException ioe)

System.err.println("IOException: " + ioe.getMessage());

} }

Méthode «GetClientMessage» :
Lors ce qu’un client envoie un message au serveur, ce dernier fait appel à cette méthode pour
qu’il affiche ce qu’il a reçu sur l’interface graphique.

22
public static void getClientMessage(String args[])

confirmation="The client " + args[1] + " has sent " + args[0] + "\n";

Méthode «initComponents» :
Chargée juste de l’initialisation des composants graphiques de l’interface.
private void initComponents() {

jMenuItem3 = new javax.swing.JMenuItem(); jMenuBar2 = new javax.swing.JMenuBar(); jMenu3 = new

javax.swing.JMenu(); jMenu4 = new javax.swing.JMenu(); jScrollPane1 = new javax.swing.JScrollPane(); jTextArea1 =

new javax.swing.JTextArea(); jTextArea1.setForeground(new Color(50, 205, 50)); jTextArea1.setBackground(new Color(0,

0, 0)); jScrollPane2 = new javax.swing.JScrollPane(); jTextArea2 = new javax.swing.JTextArea();

jTextArea2.setForeground(new Color(50, 205, 50)); jTextArea2.setBackground(new Color(0, 0, 0)); jMenuBar1 = new

javax.swing.JMenuBar();

23
jMenuBar1.setForeground(new Color(0, 0, 0));

jMenuBar1.setBackground(new Color(50, 205, 50));

jMenu1 = new javax.swing.JMenu();

jMenu1.setForeground(new Color(255, 255, 255));

jMenuItem1 = new javax.swing.JMenuItem();

jMenu2 = new javax.swing.JMenu();

jMenu2.setForeground(new Color(255, 255, 255));

jMenuItem2 = new javax.swing.JMenuItem();

jMenu5 = new javax.swing.JMenu();

jMenu5.setForeground(new Color(255, 255, 255));

jMenuItem4 = new javax.swing.JMenuItem();

jMenuItem3.setText("jMenuItem3");

jMenu3.setText("File");

jMenuBar2.add(jMenu3);

jMenu4.setText("Edit");

jMenuBar2.add(jMenu4);

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

setTitle("Server 127.0.0.1 Port : 7344");

jTextArea1.setColumns(20);

jTextArea1.setRows(5);

jTextArea1.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new
java.awt.Color(0, 0, 0), 2), "Server Report", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.TOP, new java.awt.Font("Calibri", 1, 14)));
jScrollPane1.setViewportView(jTextArea1);

jTextArea2.setColumns(10);

24
jTextArea2.setRows(5);

jTextArea2.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createLineBorder(new
java.awt.Color(0, 0, 0), 2), "State Table", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Calibri", 1, 14)));
jScrollPane2.setViewportView(jTextArea2);

jMenuBar1.setBorder(null); jMenuBar1.setCursor(new

java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); jMenuBar1.setFont(new

java.awt.Font("Segoe UI", 0, 48));

jMenu1.setText("Server");

jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q,

java.awt.event.InputEvent.CTRL_MASK)); jMenuItem1.setText("Stop & Quit");

jMenuItem1.addActionListener(new java.awt.event.ActionListener() { public void

actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem1ActionPerformed(evt);

});

jMenu1.add(jMenuItem1);

jMenuBar1.add(jMenu1);

jMenu2.setText("Rules");

jMenuItem2.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R,
java.awt.event.InputEvent.CTRL_MASK)); jMenuItem2.setText("Server Rules");
jMenuItem2.addActionListener(new java.awt.event.ActionListener() { public void
actionPerformed(java.awt.event.ActionEvent evt) {

25
jMenuItem2ActionPerformed(evt);

});

jMenu2.add(jMenuItem2);

jMenuBar1.add(jMenu2);

jMenu5.setText("View");

jMenuItem4.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_L,

java.awt.event.InputEvent.CTRL_MASK)); jMenuItem4.setText("View Log");

jMenuItem4.addActionListener(new java.awt.event.ActionListener() { public void

actionPerformed(java.awt.event.ActionEvent evt) { jMenuItem4ActionPerformed(evt);

});

jMenu5.add(jMenuItem4);

jMenuBar1.add(jMenu5);

setJMenuBar(jMenuBar1);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

layout.setHorizontalGroup( layout.createParallelGroup(Alignment.LEADING)

.addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 593, Short.MAX_VALUE)

.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 613, Short.MAX_VALUE)

);

layout.setVerticalGroup(

26
layout.createParallelGroup(Alignment.TRAILING)

.addGroup(layout.createSequentialGroup()

.addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 268, GroupLayout.PREFERRED_SIZE)

.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

.addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,


GroupLayout.PREFERRED_SIZE))

);

getContentPane().setLayout(layout);

pack();

private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {

ServerRules sr = new ServerRules();

private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt) {

try{

LogWindow l = new LogWindow();

catch(Exception e){}

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {

private javax.swing.JMenu jMenu1;


private javax.swing.JMenu jMenu2; private
javax.swing.JMenu jMenu3; private
javax.swing.JMenu jMenu4; private
javax.swing.JMenu jMenu5; private
javax.swing.JMenuBar jMenuBar1;

private javax.swing.JMenuBar jMenuBar2; private javax.swing.JMenuItem jMenuItem1; private

javax.swing.JMenuItem jMenuItem2; private javax.swing.JMenuItem jMenuItem3; private javax.swing.JMenuItem

27
jMenuItem4; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private

javax.swing.JTextArea jTextArea1; private javax.swing.JTextArea jTextArea2;

Fichier LogWindow.java:
Cette classe représente une interface graphique qui a pour but d'afficher toutes les
activités avec leurs dates qui sont dans le fichier log.txt afin de garder l’historique de
l’utilisateur.

Constructeur «LogWindow» :
• S’occupe ici de l’appel de composants d’interface ;
• De charger les activités qui existent déjà du fichier (log.txt) dans l’interface.
public LogWindow() throws Exception{ setResizable(false);

getContentPane().setBackground(new Color(0, 0, 0)); initComponents();

this.setVisible(true);

File file = new File("log.txt");

FileInputStream fis = new FileInputStream(file);


byte[] data = new byte[(int)file.length()]; fis.read(data);

fis.close();

String s = new String(data, "UTF-8"); jTextArea1.setText(s);

Méthode «initComponents» :
Chargée juste de l’initialisation des composants graphiques de l’interface.

28
private void initComponents() { jScrollPane1 =

new javax.swing.JScrollPane(); jTextArea1 = new

javax.swing.JTextArea();

jTextArea1.setForeground(new Color(50, 205, 50));

jTextArea1.setBackground(new Color(0, 0, 0));

jTextArea1.setBorder(null);

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE)
; setTitle("Log

Window");

jTextArea1.setColumns(20);

jTextArea1.setRows(5);

jScrollPane1.setViewportView(jTextArea1);

javax.swing.GroupLayout layout = new


javax.swing.GroupLayout(getConten tPane());
getContentPane().setLayout(layout); layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG)

.addGroup(layout.createSequentialGroup()

29
.addContainerGap()

.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_
SIZE, 371, javax.swing.GroupLayout.PREFERRED_SIZE)

.addContainerGap(19, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG)

.addGroup(layout.createSequentialGroup()

.addContainerGap()

.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SI
ZE, 278, Short.MAX_VALUE)

.addContainerGap())

);

pack();

}
class ServerRules:
Cette classe vas nous permettre de définir les règles sur le serveur, c’est-à-dire qu’on
peut ajouter des mots dans une blackliste des strings (stringblock.txt), ou supprimer cette
étape a pour but que lorsque le serveur reçoit un message contient un mot de ces mots
qui sont définis dans la blacklist automatiquement le mot ne s'accepte pas, pareil pour
une blacklist des adresses IP (block.txt).

Constructeur «ServerRules» :
• S’occupe ici de l’appel de composants d’interface ;
• Charger la liste des adresses IP qui existent dans le fichier block.txt ;
30
• Charger la liste des mots qui existent déjà dans le fichier stringblock.txt.
public ServerRules() { setResizable(false);

getContentPane().setBackground(new Color(0, 0, 0));

initComponents(); this.setVisible(true);

list.setForeground(new Color(50, 205, 50));

list.setBounds(100,100,100,200);

list.setLocation(50, 50); list.setVisible(true);

list2.setForeground(new Color(50, 205, 50));

list2.setBounds(100,100,100,200);

list2.setLocation(380, 50); list2.setVisible(true);

getContentPane().add(list);

getContentPane().add(list2);

getContentPane().validate();

getContentPane().repaint(); this.pack();

try

FileInputStream fstream = new FileInputStream("block.txt");

DataInputStream in = new DataInputStream(fstream);

BufferedReader br = new BufferedReader(new InputStreamReader(in))


;

31
String strLine; while

((strLine = br.readLine()) != null)

if(strLine.equals("XXX.XXX.XXX.XXX")==false)

listModel.addElement(strLine);//charger la liste des adres


ses ip interdits qui existent

in.close();

}catch(Exception e){}

try

FileInputStream fstream = new FileInputStream("stringblock.txt");

DataInputStream in = new DataInputStream(fstream);

BufferedReader br = new BufferedReader(new InputStreamReader(in))


;

String strLine; while

((strLine = br.readLine()) != null)

listModel2.addElement(strLine);//charger la liste par les mots


interdit qui existent

in.close();

}catch(Exception e){}

setSize(550,350);

Méthode « jButton1ActionPerformed» :
Cette méthode s’exécute lors d’un évènement sur le JButton1 (click) :

32
• Une fenêtre de dialogue s’affiche demandant de saisir une nouvelle adresse IP
que vous souhaitez d’être bloquée ;
• Si l’adresse IP saisit est du format XXX.XXX.XXX.XXX elle sera enregistrer
dans le fichier block.txt comme une adresse interdite ;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

String input = JOptionPane.showInputDialog(this ,"Ajouter une


addres se IP pour qu'elle soit bloque :");

Pattern pat = Pattern.compile("[0-2]?[0-9]?[0-9].[0-2]?[0-9]?[0-


9].[0-2]?[0-9]?[0-9].[0-2]?[0-9]?[0-9]");

Matcher mat = pat.matcher(input);

if(mat.matches())

listModel.addElement(input);

try

String filename= "block.txt";

FileWriter fw = new

FileWriter(filename,true); fw.write(input +

"\n"); fw.close();

catch(IOException ioe)

System.err.println("IOException: " + ioe.getMessage());

else

JOptionPane.showMessageDialog(rootPane, "Please enter a valid IP A


dress"); }

Méthode «JButton1ActionPerformed» :
Cette méthode s’exécute lors d’un évènement sur le JButton2 (click) : elle a pour but de
supprimer l’adresse IP sélectée de la liste ainsi de remplacer sans emplacement dans le
fichier block.txt par des XXX.XXX.XXX.XXX

33
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

int selectedIndex = list.getSelectedIndex();

String str2delete = list.getSelectedValue().toString();

try {

BufferedReader file = new BufferedReader(new


FileReader("block.txt "));

String line;String input = ""; while ((line =

file.readLine()) != null) input += line + '\n'; input =

input.replace(str2delete, "XXX.XXX.XXX.XXX");

FileOutputStream File = new FileOutputStream("block.txt");

File.write(input.getBytes());

} catch (Exception e) {

System.out.println("Problem reading file.");

} if

(selectedIndex != -1) {

//si un element de la liste est selectez

listModel.removeElementAt(selectedIndex);

Méthode «jButton3ActionPerformed || jButton6ActionPerformed» :


Ces méthodes servent à quitter la fenêtre de ServerRules.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {

dispose();

Méthode «jButton4ActionPerformed» :
Cette méthode s’exécute lors d’un évènement sur le JButton1 (click) :
• Une fenêtre de dialogue s’affiche demandant de saisir un nouveau mot que vous
souhaitez d’être bloquée ;
• Le mot saisi sera enregistré dans le fichier stringblock.txt

34
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {

String input = JOptionPane.showInputDialog(this ,"Ajouter un mot


pour qu'il soit bloqu :");

//ajouter un mot interdit a la liste dans le fichier

stringblock.txt listModel2.addElement(input); try

String filename= "stringblock.txt";

FileWriter fw = new

FileWriter(filename,true); fw.write(input +

"\n"); fw.close();

catch(IOException ioe)

System.err.println("IOException: " + ioe.getMessage());

Méthode «jButton5ActionPerformed» :
Supprimer le mot sélecté de la liste et de remplacer son emplacement dans le fichier
stringblock.txt par une chaine vide.
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {

int selectedIndex = list2.getSelectedIndex();

String str2delete = list2.getSelectedValue().toString();

try {

BufferedReader file = new BufferedReader(new FileReader("stringblo


ck.txt"));

String line;String input = "";

35
while ((line = file.readLine()) != null) input += line + '\n';

input = input.replace(str2delete, "");

FileOutputStream File = new FileOutputStream("stringblock.txt");

File.write(input.getBytes());

} catch (Exception e) {

System.out.println("Problem reading file.");

} if

(selectedIndex != -1) {

listModel2.removeElementAt(selectedIndex);

}
Fichier Client.java:
Cette classe client marche sur un autre Thread indépendant de serveur, elle présente une
interface graphique pour le client, le permettant de se connecter au serveur et de lui
envoyer des messages aussi.

Données :

36
// définition d'un point de terminaison interne pour l'envoi ou la réception de données
Socket client;

// définition des gestionnaires de flux

InputStream clientIn;

OutputStream clientOut;

PrintWriter pw;

BufferedReader br, stdIn;

String ip="";

// un nouveau thread indépendant du serveur

Thread tc = new Thread();

// definition d'un pattern pour la verification du validation des @IPs

private static final String IPADDRESS_PATTERN =

"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +

"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +

"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +

"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

Pattern pattern = Pattern.compile(IPADDRESS_PATTERN);

Matcher matcher;

// Déclaration des Composants d'interface graphique


private JFrame frame; private JTextField IpInput;
private JTextField portInput; private JLabel
lblLiveChatBg; private JTextField msgInput;
private JLabel lblOnMode; private static int
lastPosition = 0;

Constructeur :
Démarre le Thread déclaré précédemment et fait appel à la méthode d’initialisation des
composants graphique.
public Client() {

tc.start(); initialize();

37
Méthode «initialize» :
/**

* Initialisation des composants de l'interface

*/ private void initialize() { //initialisation du

fenetre frame = new JFrame();

frame.getContentPane().setBackground(Color.WHITE);

//positionnement frame.setBounds(100, 100, 350, 510);

frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

frame.getContentPane().setLayout(null); JLabel startBtn = new JLabel("");

startBtn.setBounds(300, 18, 40, 26); startBtn.setIcon(new

ImageIcon(Client.class.getResource("/startBtn.png")));

// Code executé lors de clique sur le bouton de connextion

startBtn.addMouseListener(new MouseAdapter() {

@Override public void

mouseClicked(MouseEvent e) {

//For connecting to the server

int flag=0;

String args[] = new String[2];


ip=IpInput.getText();

38
matcher = pattern.matcher(ip); // Si

l'@IP entrée est valide if(matcher.matches()

&& !ip.startsWith("0"))

// se connecter au serveur et initialisation des gestionnaires de flux de données client-serveur

try

client =new Socket(ip,Integer.parseInt(portInput.getText()));

clientIn =client.getInputStream(); clientOut

=client.getOutputStream(); pw = new PrintWriter(clientOut, true);

br = new BufferedReader(new InputStreamReader(clientIn));

stdIn = new BufferedReader(new InputStreamReader(System.in));

//Affichage d'un message au client en cas d'echec de connexion au serveur

catch(ConnectException ce)

JOptionPane.showMessageDialog(frame, "Server Not Found");

flag=1;

System.out.println("Cannot connect to the server.");

catch (IOException ie)

{}

FileInputStream fstream;

java.util.List<String> list=new ArrayList<>();

// Lire les mots interdits stoqués sur le ficher block.txt et les ajoutés dans la list déclarée ci-dessus

try

fstream = new FileInputStream("block.txt");

39
DataInputStream in = new DataInputStream(fstream);

BufferedReader br = new BufferedReader(new InputStreamReader(in));

String strLine; while

((strLine = br.readLine()) != null)

list.add(strLine.trim());

catch(Exception e1){}

// si l'@IP du client est présente dans la liste noire, un message d'erreur s'affiche , sinon une connexion vers le
serveur est bien établi.

if(list.contains(ip))

try

JOptionPane.showMessageDialog(frame, "You're not allowed to access this server", "Banned",


JOptionPane.ERROR_MESSAGE);

client.close();

catch(IOException e1){}

else {

if(flag!=1)

JOptionPane.showMessageDialog(frame, "Successfully Connected to the Server");

lblOnMode.setVisible(true);

System.out.println("Successfully connected to the server.");

40
else

JOptionPane.showMessageDialog(frame, "Please enter valid IP Address");

});

frame.getContentPane().add(startBtn); lblOnMode = new JLabel("");

lblOnMode.setBounds(0, 70, 350, 89); lblOnMode.setIcon(new

ImageIcon(Client.class.getResource("/onMode.png")));

frame.getContentPane().add(lblOnMode); lblOnMode.setVisible(false);

// Champ d'IP

JLabel lblNewLabel = new JLabel("SERVER IP");

lblNewLabel.setBounds(6, 23, 69, 16);

frame.getContentPane().add(lblNewLabel);

IpInput = new JTextField();

IpInput.setBounds(68, 18, 130, 26);

IpInput.setDocument(new JTextFieldLimit(15));

frame.getContentPane().add(IpInput);

IpInput.setColumns(10);

// Champ de port

JLabel lblPort = new JLabel("PORT");

lblPort.setBounds(200, 23, 38, 16);

frame.getContentPane().add(lblPort); portInput =

new JTextField(); portInput.setBounds(235, 18,

62, 26); portInput.setDocument(new

JTextFieldLimit(4));

frame.getContentPane().add(portInput);

portInput.setColumns(10);

41
JSeparator separator = new JSeparator();

separator.setBackground(new Color(164,219,251,70));

separator.setBounds(81, 474, 227, 9);

frame.getContentPane().add(separator);

// Champ pour le message msgInput = new

JTextField(); msgInput.setBackground(new

Color(4,170,255));

msgInput.setForeground(Color.WHITE);

msgInput.setBounds(83, 453, 217, 28);

msgInput.setBorder(null);

msgInput.setColumns(10);

msgInput.setDocument(new JTextFieldLimit(25));

msgInput.setText("type a message for server");

msgInput.addMouseListener(new MouseAdapter() {

@Override public void

mouseClicked(MouseEvent e) { //

TODO Auto-generated method stub

super.mouseClicked(e);

msgInput.setText("");

});

frame.getContentPane().add(msgInput); JScrollPane scrollPane = new JScrollPane();

scrollPane.setBorder(null);

scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

JPanel container = new JPanel() ; container.setBorder(null); container.setBackground(new

Color(0,128,255)); container.setLayout(null);

42
container.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);

container.setPreferredSize(new Dimension(350,60));

scrollPane.setViewportView(container); scrollPane.setBounds(0, 163, 350,

250); frame.getContentPane().add(scrollPane); JLabel sendBtn = new

JLabel(""); sendBtn.setBounds(306, 453, 38, 30);

// code exécuté lors du clique sur le bouton d'envoi d'un message au serveur

sendBtn.addMouseListener(new MouseAdapter() {

@Override public void

mouseClicked(MouseEvent e) {

// TODO Auto-generated method stub

// Si aucune @Ip client est disponible pour le moment on affiche un message demandant au client de se connecter
avant d'envoyer des messages.

if(ip.equals(""))

JOptionPane.showMessageDialog(frame, "First of all Connect.\nThen send the message.", "Error",


JOptionPane.ERROR_MESSAGE);

//Sinon en envoi le message au serveur

else

int containerWidth = scrollPane.getPreferredSize().width; int

containerHeight = scrollPane.getPreferredSize().height;

container.setPreferredSize(new Dimension(containerWidth,containerHeight+90));

container.revalidate();

JPanel Msg = new JPanel();

Client.lastPosition+=44;

Msg.setBounds(17, Client.lastPosition, 236, 30);

Msg.setBackground(new Color(0,128,255));

Msg.setBorder(null);
Msg.setLayout(null);
container.add(Msg);

43
JLabel text = new JLabel(msgInput.getText());

text.setForeground(Color.WHITE); text.setBounds(21,

6, 180, 16);

Msg.add(text);

JLabel msgBg = new JLabel(""); msgBg.setBounds(0, 0, 262,

30); Msg.add(msgBg); msgBg.setIcon(new

ImageIcon(Client.class.getResource("/blueMsg.png")));

int i=0,l=0;

pw.println(msgInput.getText()); //

Reception de la réponse du serveur

try

String div[] = br.readLine().trim().split("#");

l=div.length;

String response = "";

for(i=0;i<l;i++)

response += div[i];

JPanel MsgBack = new JPanel();

Client.lastPosition+=44;

MsgBack.setBounds(90, Client.lastPosition, 236, 30);

MsgBack.setBackground(new Color(0,128,255));

MsgBack.setBorder(null);

container.add(MsgBack);

MsgBack.setLayout(null);

JLabel textBack = new JLabel(response);

textBack.setBounds(17, 6, 180, 16);

MsgBack.add(textBack);

44
textBack.setForeground(new Color(17,127,246)); JLabel

msgBackBg = new JLabel(""); msgBackBg.setBounds(0, 0, 236, 30);

MsgBack.add(msgBackBg); msgBackBg.setIcon(new

ImageIcon(Client.class.getResource("/whiteMsg.png"))); msgInput.setText("");

catch(Exception e1){}

});

frame.getContentPane().add(sendBtn);

// image de derriere plan lblLiveChatBg = new JLabel("");

lblLiveChatBg.setBounds(0, 73, 350, 415); lblLiveChatBg.setIcon(new

ImageIcon(Client.class.getResource("/liveChat.png")));

frame.getContentPane().add(lblLiveChatBg); frame.setVisible(true);

// Classe pour limiter la taille des charactères entrées dans un champ de texte "JTextField"

class JTextFieldLimit extends PlainDocument {

private int limit;

JTextFieldLimit(int limit) {

super(); this.limit = limit;

JTextFieldLimit(int limit, boolean upper) {

super();

this.limit = limit;

45
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {

if (str == null) return;

if ((getLength() + str.length()) <= limit) {

super.insertString(offset, str,attr); }

class Firewall
C’est la classe principale qui s’exécute la première, chargée de lancer le serveur et les
clients.

La méthode «main» :
S’occupe de l’instanciation d’un Thread pour le serveur et deux autres comme clients.
public static void main(String[] args) {

new ServerThread().start();
new ClientThread1().start();
new ClientThread2().start();
}

class ServerThread extends Thread

{ public void

run()

// instancier un serveur
Server s = new Server();
}

} class ClientThread1 extends

Thread

{ public void

run()

// instancier un client

Client c = new Client();

46
Chapitre III : Server Proxy

Un serveur proxy est un serveur qui se trouve entre le client et le serveur distant dans
lequel le client souhaite récupérer des fichiers. Tout le trafic qui provient du client, est
envoyé au serveur proxy et le serveur proxy fait des demandes au serveur distant au nom
du client. Une fois que le serveur proxy reçoit les fichiers requis, il les transmet au client.
Cela peut être bénéfique car il permet à l’administrateur du serveur proxy de contrôler
ce que les machines sur son réseau peuvent faire. Par exemple, certains sites Web
peuvent être bloqués par le serveur proxy, ce qui signifie que les clients ne pourront pas
y accéder. Il est également bénéfique que les pages fréquemment visitées peuvent être
mis en cache par le serveur proxy.
Cela signifie que lorsque le client (ou d’autres clients) font des demandes ultérieures
pour des fichiers qui ont été mis en cache, le Proxy peut leur remettre les fichiers
immédiatement, sans avoir à les demander depuis le serveur distant ce qui peut être
beaucoup plus rapide si le proxy et les clients sont sur le même réseau. Bien que ces
fichiers soient connus pour être contenus dans le cache du proxy, il est intéressant de
noter que les clients n’ont aucune connaissance de cela et peuvent maintenir leurs
propres caches locaux.

Figure 7 : fonctionnement du serveur.

1. Les fonctionnalités d’un serveur PROXY

Désormais, avec l'utilisation de TCP/IP au sein des réseaux locaux, le rôle de relais
du serveur proxy est directement assuré par les passerelles et les routeurs. Pour autant,
les serveurs proxy sont toujours d'actualité grâce à un certain nombre d'autres
fonctionnalités.

Le cache :
Un serveur proxy ayant la possibilité de cacher (néologisme signifiant "mettre en
mémoire cache") les informations est généralement appelé "serveur proxy-cache".
47
Cette fonctionnalité implémentée dans certains serveurs proxy permet d'une part de
réduire l'utilisation de la bande passante vers internet ainsi que de réduire le temps
d'accès aux documents pour les utilisateurs.
Le filtrage :
Il est ainsi possible de filtrer les connexions à internet en analysant d'une part les requêtes
des clients, d'autre part les réponses des serveurs. Lorsque le filtrage est réalisé en
comparant la requête du client à une liste de requêtes autorisées, on parle de liste
blanche, lorsqu'il s'agit d'une liste de sites interdits on parle de liste noire. Enfin l'analyse
des réponses des serveurs conformément à une liste de critères (mots-clés, ...) est appelé
filtrage de contenu

L'authentification :
Il est parfois possible de l'utiliser pour authentifier les utilisateurs, c'est-à-dire de leur
demander de s'identifier à l'aide d'un nom d'utilisateur et d'un mot de passe par exemple.
Il est ainsi aisé de donner l'accès aux ressources externes aux seules personnes autorisées
à le faire et de pouvoir enregistrer dans les fichiers journaux des accès identifiés.

Les reverse-proxy :
On appelle reverse-proxy (en français le terme de relais inverse est parfois employé) un
serveur proxy-cache "monté à l'envers", c'est-à-dire un serveur proxy permettant non pas
aux utilisateurs d'accéder au réseau internet, mais aux utilisateurs d'internet d'accéder
indirectement à certains serveurs internes.

2. Server proxy en java

a) Implémentation

Le proxy a été implémenté en utilisant Java et a fait une large utilisation des sockets
TCP. Firefox a été mis en place pour émettre tout son trafic vers le port spécifié et
l’adresse IP qui ont ensuite été utilisés dans la configuration proxy. Il y a deux
composantes principales à l’implémentation - la classe Proxy et la classe
Requesthandler.

b) Les classes
La classe Proxy
La classe Proxy est responsable de la création d’un Serversocket qui peut accepter les
connexions socket entrantes du client. Cependant, il est essentiel que l’implémentation
soit multithreadée car le serveur doit pouvoir servir plusieurs clients simultanément.
Ainsi, une fois qu’une connexion socket arrive, elle est acceptée et le Proxy crée un
nouveau thread qui dessert la requête (voir la classe Requesthandler). Comme le serveur
n’a pas besoin d’attendre que la requête soit entièrement réparée avant d’accepter une
nouvelle connexion de socket, plusieurs clients peuvent avoir leurs demandes traitées de
manière asynchrone.
48
La classe Proxy est également responsable de l’implémentation de la fonctionnalité de
cache et de blocage. Autrement dit, le proxy est capable de mettre en cache les sites qui
sont demandés par les clients et de bloquer dynamiquement les clients de visiter certains
sites Web. Comme la vitesse est de la plus haute importance pour le serveur proxy, il est
souhaitable de stocker les références aux sites actuellement bloqués et les sites qui sont
contenus dans le cache dans une structure de données avec un temps de recherche
d’ordre constant attendu. Pour cette raison, un Hashmap a été choisi. Il en résulte un
cache extrêmement rapide et des temps de recherche de site bloqués. Cela n’entraîne
qu’un léger surcoût si le fichier n’est pas contenu dans le cache, et une augmentation des
performances si le fichier est contenu dans le cache.
Enfin, la classe proxy est également responsable de fournir un système de gestion
dynamique de console, Cela permet à un administrateur d’ajouter/supprimer des fichiers
vers et depuis le cache et les sites Web vers et depuis la liste noire, en temps réel.

La Classe RequestHandler
La classe Requesthandler est chargée de traiter les demandes qui parviennent au proxy.
Le demandeur examine la demande reçue et la traite de façon appropriée. Les requêtes
peuvent être subdivisées en trois catégories principales - requêtes HTTP GET, requêtes
HTTP GET pour le fichier contenu dans le cache et requêtes HTTPS CONNECT.

Requête HTTP
Il s’agit des demandes standards faites lorsqu’un client tente de charger une page Web.
L’entretien de ces demandes est une tâche simple :
-Analysez l’URL associée à la requête.
-Créez une connexion HTTP à cette URL.
-Faire écho à la requête GET du client vers le serveur distant.
-Faire écho à la réponse du serveur au client.
-Enregistrez une copie locale du fichier dans le cache du proxy.

Requête HTTP pour les fichiers en cache


Comme avant, ce sont les requêtes typiques faites par les clients, seulement dans ce cas,
le fichier est contenu dans le cache du proxy.
-Analysez l’URL associée à la requête
-Hachez l’URL et utilisez-la comme clé pour la structure de données Hashmap.
-Ouvrir le fichier résultant pour lecture.
-Renvoyer le contenu du fichier au client.
-Fermer le dossier.

Requête HTTPS - Requête CONNECT


Les connexions HTTPS utilisent des sockets sécurisés (SSL). Les données transférées
entre le client et le serveur sont cryptées. Ce système est largement utilisé dans le secteur
financier pour garantir la sécurité des transactions, mais il est de plus en plus répandu
sur Internet.

49
Cependant, à première vue, cela pose un problème pour les serveurs proxy : Comment
le proxy sait-il quoi faire avec ces données cryptées provenant du client ?
Afin de résoudre ce problème, au départ, un autre type de requête HTTP est fait par le
client, une requête CONNECT. Cette requête est HTTP standard et est donc non cryptée
et contient l’adresse avec laquelle le client souhaite créer une connexion HTTPS et peut
être extraite par le proxy. Il s’agit d’un processus connu sous le nom de tunnel HTTP
Connect et fonctionne comme suit :
-Le client émet une demande CONNECT
-Proxy extrait l’URL de destination.
-Proxy crée une connexion socket standard vers le serveur distant spécifié par l’URL.
-En cas de succès, le proxy envoie une réponse « 200 Connection Established » au client,
indiquant que le client peut maintenant commencer à transmettre les données chiffrées
au proxy.
-Le proxy transfère alors simultanément toutes les données envoyées par le client au
serveur distant et toutes les données reçues par le serveur distant au client.

Toutes ces données seront cryptées et donc le proxy ne peut pas mettre en cache ni même
interpréter les données.

50
Chapitre IV : Systèmes de détection d’intrusion
(IDS)

La détection des intrusions est le processus de surveillance des événements se trouvant


dans un système des ordinateurs ou du réseau et les analysant pour détecter les signes
des intrusions, défini comme des tentatives pour compromettre la confidentialité,
intégrité, disponibilité ou éviter des mécanismes de sécurité de l’ordinateur ou du réseau.
L’intrusion est causée par les attaques accédant au système via l’Internet, autorisée
l’utilisateur du système qui essayer à gagner les privilèges supplémentaires pour lesquels
ils n’ont pas autorisés, et autorisé les utilisateurs qui abusent les privilèges donnés. Le
système de détection des intrusions est un logiciel ou un matériel qui automatise des
surveillances et les processus analysés.

1. Les différents types d’IDS

On peut dans un premier temps classer tous les outils de détection d'intrusion selon
deux modes de fonctionnement selon qu'ils se basent sur des signatures d'attaques
ou sur des modèles comportementaux. IDS à Bibliothèques de signatures :

Généralement, les IDS réseaux se basent sur un ensemble de signatures qui représentent
chacune le profil d'une attaque. Cette approche consiste à rechercher dans l'activité de
l'élément surveillé (un flux réseau) les empreintes d'attaques connues, à l'instar des anti-
virus.
Une signature est habituellement définie comme une séquence d'événements et de
conditions relatant une tentative d'intrusion. La reconnaissance est alors basée sur le
concept de "pattern matching" (analyse de chaînes de caractères présente dans le paquet,
à la recherche de correspondance au sein d'une base de connaissance). Si une attaque est
détectée, une alarme peut être remontée (si l'IDS est en mode actif, sinon, il se contente
d'archiver l'attaque).

2. IDS à Modèles comportementaux :


Les IDS comportementaux ont pour principale fonction la détection d'anomalie. Leur
déploiement nécessite une phase d'apprentissage pendant laquelle l'outil va apprendre le
comportement "normal" des flux applicatifs présents sur son réseau. Ainsi, chaque flux
et son comportement habituel doivent être déclaré ; l'IDS se chargera d'émettre une
alarme, si un flux anormal est détecté, et ne pourra bien entendu, spécifier la criticité de
l'éventuelle attaque.
Les IDS comportementaux sont apparus bien plus tard que les IDS à signature et ne
bénéficient pas encore de leur maturité. Ainsi, l'utilisation de tels IDS peut s'avérer
délicate dans le sens où les alarmes remontées contiendront une quantité importante de
fausses alertes. Ce problème peut être résolu en généralisant la déclaration des flux mais
51
cette opération peut entrainer une transparence de l'IDS face à la détection de certaines
attaques.

3. IDS réseau et IDS système

Les IDS peuvent également se classer selon deux catégories majeures selon qu'ils
s'attachent à surveiller le trafic réseau ou l'activité des machines. On parle d'IDS réseau
(NIDS : Network IDS) ou d'IDS Système (Host based IDS).

Figure 8: Networtk based IDS et Host based IDS

Les N-IDS, assurent la sécurité au niveau du réseau :

Les IDS réseaux (Network IDS), analysent en temps réel le trafic qu'ils aspirent à l'aide
d'une sonde. Ensuite, les paquets sont décortiqués puis analysés. En cas, de détection
d'intrusion, des alertes peuvent être envoyées.
Ils peuvent être placés à divers endroits sur le réseau, en amont ou en aval d'un pare feu
ou encore sur chaque hôte, comme un antivirus. Ces IDS vont analyser tout le trafic
entrant et sortant du réseau afin d'y déceler des attaques. Les H-IDS, assurent la
sécurité au niveau des hôtes :

Les IDS systèmes (Host IDS), quant à eux, analysent le fonctionnement et l'état des
machines sur lesquels ils sont installés afin de détecter les attaques en se basant sur des
démons (tels que syslogd par exemple). L'intégrité des systèmes est alors vérifiée
périodiquement et des alertes peuvent être levées. Par nature, ces IDS sont limités et ne
peuvent détecter les attaques provenant des couches réseaux (tels que les attaques de
type DOS).
La fonction de base d'un HIDS est l'inspection des fichiers de configuration du système
d'exploitation afin d'y déceler des anomalies et agissent comme des antivirus mais en
plus poussé, car les antivirus ne sont intéressés que par les activités malveillantes du
poste alors qu'un HIDS va pouvoir intervenir s'il détecte des attaques.

52
4. Systèmes de détection d’intrusion (IDS) en java

On appelle IDS (Intrusion Detection System) un mécanisme écoutant le trafic réseau de


manière furtive afin de repérer des activités anormales ou suspectes et permettant ainsi
d’avoir une action de prévention sur les risques d’intrusion.

a) Port scannig

Est une technique utilisée par les attaquants pour trouver des hôtes vulnérables qui ont des
services d'écoute sur certains ports. Dans une SYN scan attaque le scanner envoie des paquets
TCP SYN et attendre les réponses des hôtes qui renvoient les paquets SYN + ACK. Comme la
plupart les hôtes ne sont pas prêts à recevoir des connexions sur un port donné pendant le
scanning, un petit nombre d'hôtes répondra avec des paquets SYN + ACK que les paquets SYN
reçus à l'origine. En observant ce phénomène dans un fichier de trace, vous pouvez identifier
adresses sources qui peuvent lancer une analyse de port.

Prérequis
Jnetpcap : jnetpcap est une librairie de java open-source, elle peut être utilisée pour
capturer et décoder des données en ligne ainsi que hors ligne.
Portscan.pcap : un fichier de capture des paquets résultant d’une attaque «Port scanning»

b) Explication du projet

Le projet contient une seule classe ScannerFinder qui permet d’analyser un


fichier
‘’.pcap’’ pour détecter une éventuelle attaque en se basant sur la technique du port
scanning dont la sortie du programme est une adresse IP qui a envoyée plus de 3
fois plus de paquets SYN que le nombre de paquets SYN + ACK qu'elle a reçu.

Constructeur ScannerFinder():
Prend en paramètre le chemin vers le fichier ‘’.pcap’’ pour l’analyser
public ScannerFinder(final String path) {

Ouvre un fichier nommé ‘’.pcap’’ à l'aide de pcap.OpenOffline (), puis parcourt les paquets à
l'aide de ‘’loop’’
pcap.loop(Pcap.LOOP_INFINITE, new JPacketHandler<StringBuilder>() {

53
Fonction nextPacket() nextPacket est une fonction de substitution de jPacketHandler
(Handler qui est utiliser pour recevoir des paquets entièrement décodés), dans cette
fonction en fait un test Si le paquet contient SYN et ACK Incrémenter le nombre SYN
ACK de l’adresse IP de destination et poser le dans une hashMap syn_ack sinon s’il
contient juste le SYN incrementer le SYN de l’adresse IP source et le poser dans la
hashMap syn.
public void nextPacket(JPacket packet, StringBuilder errbuf) {
if (packet.hasHeader(tcp) && packet.hasHeader(ip) && tcp.flags _SYN() &&
tcp.flags_ACK()) {
//si le paquet contient SYN et ACK les deux
//incrementer SYN ACK des adresses ip de destination
String synackip = org.jnetpcap.packet.format.FormatUtils.i
p(ip.destination()); if(syn_ack.containsKey(synackip))
syn_ack.put(synackip, syn_ack.get(synackip)+1); else
syn_ack.put(synackip, 1);
}else if(packet.hasHeader(tcp) && packet.hasHeader(ip) && tcp.
flags_SYN()){ //The Packet is just SYN
//Increment the source ip's SYN count
String synip = org.jnetpcap.packet.format.FormatUtils.ip(i
p.source()); if(syn.containsKey(synip))
syn.put(synip, syn.get(synip)+1); else
syn.put(synip, 1);
}
}

c) Affichage des résultats

Pour toutes les adresses IP qui ont envoyé SYN nous vérifierons s'il y a des paquets
SYN ACK envoyés à cette IP et nous afficherons l’IP qui a envoyé plus de 3 fois plus
de paquets SYN que le nombre de paquets SYN + ACK qu'ils reçu.

for(String ssyn : syn.keySet()) //Pour tous les adresses IP qui ont envoyé SYN
if(syn_ack.containsKey(ssyn)) { //Vérification s’il y a des paquet s SYN ACK
envoyés
if(syn.get(ssyn) > 3*syn_ack.get(ssyn))
System.out.println(ssyn);
}else //sinon le serveur n'a pas répondu
System.out.println(ssyn);

54
Conclusion

Le projet de fin d’année ayant été conçu dès le départ d’une façon simple pour
nous permettre de bien développer chaque partie du projet s’est avéré bien plus
compliqué et vaste et très riche côté informations.

55

Vous aimerez peut-être aussi