FEAT: Multiclient + Crypté + Pseudo

This commit is contained in:
Lucàs
2022-12-05 13:03:14 +01:00
parent 6466284b1b
commit 75e873d44f
14 changed files with 525 additions and 196 deletions
+71 -50
View File
@@ -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();
}
}
+35
View File
@@ -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();
}
}
}
-27
View File
@@ -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());
}
}
}
+38
View File
@@ -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<ThreadServer> 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();
}
}
-75
View File
@@ -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);
}
}
}
+83
View File
@@ -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<ThreadServer> threads;
private final ObjectInputStream inputStream;
private final ObjectOutputStream outputStream;
private final KeyPair serverKeys;
private PublicKey clientKey;
private String clientPseudo;
public ThreadServer(Socket socket, ArrayList<ThreadServer> 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);
}
}
+44 -13
View File
@@ -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);
+1 -1
View File
@@ -1,4 +1,4 @@
package reseau;
package utils;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
+23
View File
@@ -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;
}
}