diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 2edd9ec..99ea954 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -2,10 +2,18 @@
+
+
+
+
+
+
-
-
+
+
+
+
@@ -15,6 +23,8 @@
@@ -33,24 +43,47 @@
- {
- "keyToString": {
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "WebServerToolWindowFactoryState": "false",
- "codeWithMe.voiceChat.enabledByDefault": "false",
- "project.structure.last.edited": "Project",
- "project.structure.proportion": "0.0",
- "project.structure.side.proportion": "0.0"
+
+}]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
@@ -71,8 +104,8 @@
-
-
+
+
@@ -84,8 +117,8 @@
-
-
+
+
@@ -97,33 +130,33 @@
-
-
+
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
@@ -138,6 +171,7 @@
+
diff --git a/key.ser b/key.ser
deleted file mode 100644
index ce92458..0000000
Binary files a/key.ser and /dev/null differ
diff --git a/projet-mini-chat.iml b/projet-mini-chat.iml
index c90834f..f9f9807 100644
--- a/projet-mini-chat.iml
+++ b/projet-mini-chat.iml
@@ -4,8 +4,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/client/Client.java b/src/client/Client.java
index 175a7a2..818f298 100644
--- a/src/client/Client.java
+++ b/src/client/Client.java
@@ -1,71 +1,92 @@
package client;
-import java.io.*;
+import utils.RSA;
+import utils.ResolutionDeNom;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.ConnectException;
import java.net.Socket;
-import java.rmi.UnknownHostException;
import java.security.KeyPair;
import java.security.PublicKey;
+import java.util.Objects;
import java.util.Scanner;
-import reseau.RSA;
-
public class Client {
- public static final Scanner scan = new Scanner(System.in);
+ private final String SERVER_IP;
+ private final int SERVER_PORT;
+ private final Scanner scanner;
+ private ObjectInputStream inputStream;
+ private ObjectOutputStream outputStream;
+ private KeyPair clientKeys;
+ private PublicKey serverKey;
- public static void main(String[] args) {
- Socket serverSocket = null;
- ObjectOutputStream out = null;
- ObjectInputStream in = null;
+ private String pseudo;
- // Clé de chiffrage
- KeyPair clientKeyPair = RSA.genererCle();
- PublicKey serverKey = null;
+ public Client(String ip, int port) {
+ this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
+ this.SERVER_PORT = port;
+ this.scanner = new Scanner(System.in);
+ this.clientKeys = RSA.genererCle();
+ }
- // Création des Sockets
- try {
- serverSocket = new Socket("localhost", 4444);
- System.out.println("Connecté au serveur");
- out = new ObjectOutputStream(serverSocket.getOutputStream());
- in = new ObjectInputStream(serverSocket.getInputStream());
+ public void start() {
+ System.out.print("Saisir un pseudo: ");
+ pseudo = scanner.nextLine();
- // On envoie la clé de chiffrage
- out.writeObject(clientKeyPair.getPublic());
+ try (Socket socket = new Socket(SERVER_IP, SERVER_PORT)) {
+ inputStream = new ObjectInputStream(socket.getInputStream());
+ outputStream = new ObjectOutputStream(socket.getOutputStream());
- serverKey = (PublicKey) in.readObject();
+ exchangeKeys();
- } catch (UnknownHostException e) {
- System.out.println("Destination unknown");
- System.exit(-1);
- } catch (IOException e) {
- System.out.println("now to investigate this IO issue");
- System.exit(-1);
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
+ sendMessage(pseudo);
- // Communication
- String message;
- byte[] messageCrypte;
- try {
+ // Ecoute du serveur
+ ListenThread threadClient = new ListenThread(this);
+ threadClient.start();
+
+ // Ecoute de l'entrée du clavier
+ System.out.println("Tappez 'bye' pour quitter\n");
+ String message;
do {
- // Envoi du message
- System.out.print("client > ");
- message = scan.nextLine();
- messageCrypte = RSA.encrypter(message, serverKey);
- out.writeObject(messageCrypte);
+ message = scanner.nextLine();
+ sendMessage(message);
+ } while (!Objects.equals(message, "bye"));
- // Reception du message
- messageCrypte = (byte[]) in.readObject();
- message = RSA.decrypter(messageCrypte, clientKeyPair.getPrivate());
- System.out.printf("serveur > %s\n", message);
- } while (!message.equals("bye"));
-
- out.close();
- in.close();
- serverSocket.close();
- }catch (IOException | ClassNotFoundException e) {
- e.printStackTrace();
+ } catch (ConnectException e) {
+ System.err.println("Serveur non trouvé");
+ }catch (EOFException e) {
+ System.err.println("Connexion perdue");
+ } catch (IOException | ClassNotFoundException e) {
+ e.printStackTrace();
}
}
+
+ public void exchangeKeys() throws IOException, ClassNotFoundException {
+ // Envoie sa clé
+ outputStream.writeObject(clientKeys.getPublic());
+
+ // Attend la clé du serveur
+ serverKey = (PublicKey) inputStream.readObject();
+ }
+
+ public void sendMessage(String message) throws IOException {
+ byte[] messageCrypte = RSA.encrypter(message, serverKey);
+ outputStream.writeObject(messageCrypte);
+ }
+
+ public String getMessage() throws IOException, ClassNotFoundException {
+ byte[] messageCrypte = (byte[]) inputStream.readObject();
+ return RSA.decrypter(messageCrypte, clientKeys.getPrivate());
+ }
+
+
+ public static void main(String[] args) {
+ Client client = new Client("localhost", 4444);
+ client.start();
+ }
}
diff --git a/src/client/ListenThread.java b/src/client/ListenThread.java
new file mode 100644
index 0000000..2f2500d
--- /dev/null
+++ b/src/client/ListenThread.java
@@ -0,0 +1,35 @@
+package client;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.net.SocketException;
+
+/**
+ * Thread for clients
+ */
+public class ListenThread extends Thread {
+
+ private final Client client;
+
+ public ListenThread(Client client) {
+ this.client = client;
+ }
+
+ @Override
+ public void run() {
+
+ try {
+ String message;
+ while (true) {
+ message = client.getMessage();
+ System.out.println(message);
+ }
+ } catch (SocketException ignored) {
+ System.out.println("Vous avez quitté le salon");
+ } catch (EOFException ignored) {
+ System.err.println("Connexion perdue");
+ }catch (IOException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/reseau/ResolutionDeNom.java b/src/reseau/ResolutionDeNom.java
deleted file mode 100644
index 26f1fa3..0000000
--- a/src/reseau/ResolutionDeNom.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package reseau;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class ResolutionDeNom {
-
- public static InetAddress getAddress(String host) {
- InetAddress address;
- try {
- address = InetAddress.getByName(host);
- return address;
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public static void main(String[] args) {
-// String input = args[0];
- String input = "www.google.com";
- InetAddress address = getAddress(input);
- if (address != null) {
- System.out.printf("%s : %s\n", input, address.getHostAddress());
- }
- }
-}
diff --git a/src/serveur/Server.java b/src/serveur/Server.java
new file mode 100644
index 0000000..e8c8516
--- /dev/null
+++ b/src/serveur/Server.java
@@ -0,0 +1,38 @@
+package serveur;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+
+public class Server {
+
+ private final int PORT;
+ private final ArrayList threads;
+
+ public Server(int port) {
+ this.PORT = port;
+ this.threads = new ArrayList<>();
+ }
+
+ public void start() {
+ try (ServerSocket serversocket = new ServerSocket(PORT)) {
+ System.out.println("Server is started...");
+ while (true) {
+ Socket socket = serversocket.accept();
+ System.out.printf("Nouvelle connexion : %s\n", socket);
+
+ ThreadServer thread = new ThreadServer(socket, threads);
+
+ threads.add(thread);
+ thread.start();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String[] args) {
+ Server serveur = new Server(4444);
+ serveur.start();
+ }
+}
diff --git a/src/serveur/Serveur.java b/src/serveur/Serveur.java
deleted file mode 100644
index d6aa216..0000000
--- a/src/serveur/Serveur.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package serveur;
-
-import reseau.RSA;
-
-import java.io.*;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.security.KeyPair;
-import java.security.PublicKey;
-import java.util.Scanner;
-
-public class Serveur {
-
- private static final int PORT = 4444;
- private static final Scanner scan = new Scanner(System.in);
-
- public static void main(String[] args) {
- ServerSocket serverSocket = null;
- Socket clientSocket = null;
-
- KeyPair serverKeyPairs = RSA.genererCle();
- PublicKey clientKey;
-
- // Connexion
- try {
- serverSocket = new ServerSocket(PORT); // Crée le serveur
- clientSocket = serverSocket.accept(); // On recherche un client
- } catch (IOException e) {
- System.out.printf("Erreur de connexion sur le port: %d\n", PORT);
- System.exit(-1);
- }
-
- // Un client a été trouvé
- System.out.println("Client connecté");
-
- ObjectInputStream in;
- ObjectOutputStream out;
-
- try {
- in = new ObjectInputStream(clientSocket.getInputStream());
- out = new ObjectOutputStream(clientSocket.getOutputStream());
-
- // On récupère la clé du client
- clientKey = (PublicKey) in.readObject();
- out.writeObject(serverKeyPairs.getPublic());
-
- // Communication
- String message;
- byte[] messageCrypte;
- do {
- // Envoi du message
- messageCrypte = (byte[]) in.readObject();
- message = RSA.decrypter(messageCrypte, serverKeyPairs.getPrivate());
- System.out.printf("client > %s\n", message);
-
-
- // Reception du message
- System.out.print("serveur > ");
- message = scan.nextLine();
- messageCrypte = RSA.encrypter(message, clientKey);
- out.writeObject(messageCrypte);
- } while (!message.equals("bye"));
-
- in.close();
- out.close();
- clientSocket.close();
- serverSocket.close();
-
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/serveur/ThreadServer.java b/src/serveur/ThreadServer.java
new file mode 100644
index 0000000..18d7cb2
--- /dev/null
+++ b/src/serveur/ThreadServer.java
@@ -0,0 +1,83 @@
+package serveur;
+
+import utils.RSA;
+
+import java.io.*;
+import java.net.Socket;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Objects;
+
+
+public class ThreadServer extends Thread {
+
+ private final ArrayList threads;
+ private final ObjectInputStream inputStream;
+ private final ObjectOutputStream outputStream;
+ private final KeyPair serverKeys;
+ private PublicKey clientKey;
+ private String clientPseudo;
+
+ public ThreadServer(Socket socket, ArrayList threads) throws IOException {
+ this.threads = threads;
+ this.outputStream = new ObjectOutputStream(socket.getOutputStream());
+ this.inputStream = new ObjectInputStream(socket.getInputStream());
+
+ this.serverKeys = RSA.genererCle();
+ }
+
+ @Override
+ public void run() {
+ try {
+ exchangeKeys();
+
+ // Récupère le pseudo
+ this.clientPseudo = getMessage();
+ sendMessageToEveryone(String.format("** %s viens de rejoindre le salon **", clientPseudo), true);
+
+ String message;
+ do {
+ message = getMessage();
+ String reply = String.format("%s : %s", clientPseudo, message);
+
+ sendMessageToEveryone(reply, true);
+ } while (!Objects.equals(message, "bye"));
+ } catch (IOException | ClassNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ threads.remove(this);
+ try {
+ sendMessageToEveryone(String.format("** %s viens de quitter le salon **", clientPseudo), true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void exchangeKeys() throws IOException, ClassNotFoundException {
+ // Attend la clé du client
+ clientKey = (PublicKey) inputStream.readObject();
+
+ // Envoie sa clé
+ outputStream.writeObject(serverKeys.getPublic());
+ }
+
+ public String getMessage() throws IOException, ClassNotFoundException {
+ byte[] messageCrypte = (byte[]) inputStream.readObject();
+ return RSA.decrypter(messageCrypte, serverKeys.getPrivate());
+ }
+
+ public void sendMessage(String message, boolean log) throws IOException {
+ byte[] messageCrypte = RSA.encrypter(message, clientKey);
+ outputStream.writeObject(messageCrypte);
+ if (log) System.out.println(message);
+ }
+
+ public void sendMessageToEveryone(String message, boolean log) throws IOException {
+ for (ThreadServer thread : threads) {
+ thread.sendMessage(message, false);
+ }
+ if (log) System.out.println(message);
+ }
+}
diff --git a/src/reseau/AES.java b/src/utils/AES.java
similarity index 56%
rename from src/reseau/AES.java
rename to src/utils/AES.java
index 5b742dd..f2eb994 100644
--- a/src/reseau/AES.java
+++ b/src/utils/AES.java
@@ -1,4 +1,4 @@
-package reseau;
+package utils;
import javax.crypto.*;
import java.io.*;
@@ -7,6 +7,13 @@ import java.security.*;
public class AES {
+ private static final String SAVE_FILE = "key.sav";
+
+ /**
+ * TODO
+ *
+ * @return
+ */
public static Key genererCle() {
Key key = null;
@@ -19,40 +26,64 @@ public class AES {
return key;
}
- public static String decrypter(byte[] msg, Key key) {
+ /**
+ * TODO
+ *
+ * @param msg
+ * @param key
+ * @return
+ */
+ public static byte[] encrypter(String msg, Key key) {
try {
- Cipher cipher = Cipher.getInstance("DES") ;
- cipher.init(Cipher.DECRYPT_MODE, key);
- return new String(cipher.doFinal(msg), StandardCharsets.UTF_8);
+ Cipher cipher = Cipher.getInstance("DES");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ return cipher.doFinal(msg.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
- public static byte[] encrypter(String msg, Key key){
+ /**
+ * TODO
+ *
+ * @param message
+ * @param cle
+ * @return
+ */
+ public static String decrypter(byte[] message, Key cle) {
try {
- Cipher cipher = Cipher.getInstance("DES") ;
- cipher.init(Cipher.ENCRYPT_MODE, key) ;
- return cipher.doFinal(msg.getBytes());
- } catch(Exception e){
+ Cipher cipher = Cipher.getInstance("DES");
+ cipher.init(Cipher.DECRYPT_MODE, cle);
+ return new String(cipher.doFinal(message), StandardCharsets.UTF_8);
+ } catch (Exception e) {
e.printStackTrace();
}
return null;
}
+ /**
+ * TODO
+ *
+ * @param key
+ */
public static void sauvegarderCle(Key key) {
- try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("key.ser"))) {
+ try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(SAVE_FILE))) {
objectOutputStream.writeObject(key);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
+ /**
+ * TODO
+ *
+ * @return
+ */
public static Key chargerCle() {
- Key key = null;
- try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("key.ser"))) {
+ Key key;
+ try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(SAVE_FILE))) {
key = (Key) objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
diff --git a/src/reseau/RSA.java b/src/utils/RSA.java
similarity index 98%
rename from src/reseau/RSA.java
rename to src/utils/RSA.java
index 8a2feb2..d6e19d3 100644
--- a/src/reseau/RSA.java
+++ b/src/utils/RSA.java
@@ -1,4 +1,4 @@
-package reseau;
+package utils;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
diff --git a/src/utils/ResolutionDeNom.java b/src/utils/ResolutionDeNom.java
new file mode 100644
index 0000000..c723d3b
--- /dev/null
+++ b/src/utils/ResolutionDeNom.java
@@ -0,0 +1,23 @@
+package utils;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class ResolutionDeNom {
+
+ /**
+ * TODO
+ *
+ * @param host
+ * @return
+ */
+ public static String getIPAddress(String host) {
+ String address = null;
+ try {
+ address = InetAddress.getByName(host).getHostAddress();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return address;
+ }
+}
diff --git a/test/utils/ResolutionDeNomTest.java b/test/utils/ResolutionDeNomTest.java
new file mode 100644
index 0000000..5a6d02f
--- /dev/null
+++ b/test/utils/ResolutionDeNomTest.java
@@ -0,0 +1,25 @@
+package utils;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ResolutionDeNomTest {
+
+ @Test
+ void getIPAddress() {
+
+ final int EXPECTED = 1;
+ final int ACTUAL = 0;
+ final String[][] FIXTURE = {
+ {"localhost", "127.0.0.1"},
+ {"www.univ-jfc.fr", "194.57.185.14"},
+ };
+
+ for (String[] test : FIXTURE) {
+ assertEquals(test[EXPECTED], ResolutionDeNom.getIPAddress(test[ACTUAL]));
+ System.out.printf("%s -> %s : OK\n", test[ACTUAL], test[EXPECTED]);
+ }
+
+ }
+}
\ No newline at end of file