From 68ff067a5ed65c72373ae41e26fec6950e991143 Mon Sep 17 00:00:00 2001 From: Mariano Riefolo Date: Mon, 8 Apr 2024 17:47:34 +0200 Subject: [PATCH] Fixed bigger messages bug, added working login and register, other smaller fixes --- .../java/controllers/MessageForwarder.java | 3 +- src/main/java/controllers/ServerThread.java | 75 +++++++++++++------ src/main/java/models/Rsa.java | 36 +++++++-- src/main/java/views/Client.java | 39 ++++++---- src/main/java/views/ClientReceiveThread.java | 14 ++-- src/main/java/views/ClientSendThread.java | 33 ++++---- 6 files changed, 134 insertions(+), 66 deletions(-) diff --git a/src/main/java/controllers/MessageForwarder.java b/src/main/java/controllers/MessageForwarder.java index 2e6f781..5be1b8a 100644 --- a/src/main/java/controllers/MessageForwarder.java +++ b/src/main/java/controllers/MessageForwarder.java @@ -1,5 +1,6 @@ package controllers; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -14,7 +15,7 @@ public class MessageForwarder { idThread.put(id, thread); } - public static void sendTo(int id, String message, int senderId) { + public static void sendTo(int id, String message, int senderId) throws IOException { idThread.get(id).sendMessage(message, senderId); } } diff --git a/src/main/java/controllers/ServerThread.java b/src/main/java/controllers/ServerThread.java index 122b801..ff19c31 100644 --- a/src/main/java/controllers/ServerThread.java +++ b/src/main/java/controllers/ServerThread.java @@ -13,7 +13,7 @@ import static controllers.Database.registerAccount; public class ServerThread extends Thread { private final Socket client; private BufferedReader fromClient; - private PrintWriter toClient; + private BufferedWriter toClient; private final Rsa rsa; private BigInteger clientE, clientN; private int clientId; @@ -26,13 +26,21 @@ public class ServerThread extends Thread { public void run() { try { fromClient = new BufferedReader(new InputStreamReader(client.getInputStream())); - toClient = new PrintWriter(client.getOutputStream(),true); + toClient = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); } catch (IOException e) { throw new RuntimeException(e); } - toClient.println(rsa.getE().toString()); - toClient.println(rsa.getN().toString()); + try { + send(rsa.getE().toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } + try { + send(rsa.getN().toString()); + } catch (IOException e) { + throw new RuntimeException(e); + } try { clientE = new BigInteger(fromClient.readLine()); @@ -43,8 +51,9 @@ public class ServerThread extends Thread { for (;;) { String operation; + sendEncrypted("Quale operazione vuoi effettuare? (REGISTER|LOGIN): "); try { - operation = rsa.decrypt(new BigInteger(fromClient.readLine())); + operation = rsa.decrypt(fromClient.readLine()); } catch (IOException e) { throw new RuntimeException(e); } @@ -52,10 +61,10 @@ public class ServerThread extends Thread { String username, password; try { - toClient.print("Inserisci l'username: "); - username = rsa.decrypt(new BigInteger(fromClient.readLine())); - toClient.print("Inserisci la password: "); - password = rsa.decrypt(new BigInteger(fromClient.readLine())); + sendEncrypted("Inserisci l'username: "); + username = rsa.decrypt(fromClient.readLine()); + sendEncrypted("Inserisci la password: "); + password = rsa.decrypt(fromClient.readLine()); } catch (IOException e) { throw new RuntimeException(e); } @@ -64,19 +73,23 @@ public class ServerThread extends Thread { if ("LOGIN".equals(operation)) { if (login(username, password)) { Account account = getAccount(username, password); - toClient.println(rsa.encrypt(String.valueOf(account.n()), clientE, clientN).toString()); - toClient.println(rsa.encrypt(String.valueOf(account.d()), clientE, clientN).toString()); - toClient.println(rsa.encrypt(String.valueOf(account.e()), clientE, clientN).toString()); - toClient.println(rsa.encrypt("SUCCESS", clientE, clientN).toString()); + if (account == null) { + sendEncrypted("FAIL"); + break; + } + sendEncrypted(String.valueOf(account.n())); + sendEncrypted(String.valueOf(account.e())); + sendEncrypted(String.valueOf(account.d())); + sendEncrypted("SUCCESS"); break; } } else if ("REGISTER".equals(operation)) { if (register(username, password)) { - toClient.println(rsa.encrypt("SUCCESS", clientE, clientN).toString()); + sendEncrypted("SUCCESS"); break; } } else { - toClient.println(rsa.encrypt("FAIL", clientE, clientN).toString()); + sendEncrypted("FAIL"); } } @@ -87,18 +100,36 @@ public class ServerThread extends Thread { for (;;) { try { - recipientId = Integer.parseInt(rsa.decrypt(new BigInteger(fromClient.readLine()))); - message = rsa.decrypt(new BigInteger(fromClient.readLine())); + recipientId = Integer.parseInt(rsa.decrypt(fromClient.readLine())); + message = rsa.decrypt(fromClient.readLine()); } catch (IOException e) { throw new RuntimeException(e); } if (message == null || "DISCONNECT".equals(message)) break; - MessageForwarder.sendTo(recipientId, message, clientId); + try { + MessageForwarder.sendTo(recipientId, message, clientId); + } catch (IOException e) { + throw new RuntimeException(e); + } } } + private void sendEncrypted(String text) { + try { + send(rsa.encrypt(text, clientE, clientN)); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } + + public void send(String message) throws IOException { + toClient.write(message); + toClient.newLine(); + toClient.flush(); + } + private boolean login(String username, String password) { Account account = getAccount(username, password); return account != null; @@ -119,9 +150,9 @@ public class ServerThread extends Thread { return clientId != -1; } - public void sendMessage(String message, int sender) { - toClient.println("INCOMING"); - toClient.println(sender); - toClient.println(message); + public void sendMessage(String message, int sender) throws IOException { + send("INCOMING"); + send(String.valueOf(sender)); + send(message); } } diff --git a/src/main/java/models/Rsa.java b/src/main/java/models/Rsa.java index ffc42d8..6f76f74 100644 --- a/src/main/java/models/Rsa.java +++ b/src/main/java/models/Rsa.java @@ -6,6 +6,7 @@ import java.security.SecureRandom; public class Rsa { private final BigInteger e, d, n; + private static final int CHUNK_SIZE = 64; public Rsa(int numberOfBytes) { BigInteger p = generatePrime(numberOfBytes); @@ -29,16 +30,39 @@ public class Rsa { return new BigInteger(numberOfBytes, 100, secureRandom).nextProbablePrime(); } - public BigInteger encrypt(String message, BigInteger e, BigInteger n) { - BigInteger plaintext = toHex(message); - return plaintext.modPow(e, n); + public String encrypt(String message, BigInteger e, BigInteger n) { + StringBuilder encryptedMessage = new StringBuilder(); + + for (int i = 0; i < message.length(); i += CHUNK_SIZE) { + String chunk = message.substring(i, Math.min(i + CHUNK_SIZE, message.length())); + BigInteger plaintext = toHex(chunk); + BigInteger encryptedChunk = plaintext.modPow(e, n); + encryptedMessage.append(encryptedChunk).append("|"); + } + + return encryptedMessage.toString(); + //BigInteger plaintext = toHex(message); + //return plaintext.modPow(e, n); } - public String decrypt(BigInteger ciphertext) { - BigInteger plaintext = ciphertext.modPow(d, n); - return fromHex(plaintext); + + public String decrypt(String ciphertext) { + StringBuilder decryptedMessage = new StringBuilder(); + + String[] chunks = ciphertext.split("\\|"); + + for (String chunk : chunks) { + BigInteger encryptedChunk = new BigInteger(chunk); + BigInteger decryptedChunk = encryptedChunk.modPow(d, n); + decryptedMessage.append(fromHex(decryptedChunk)); + } + + return decryptedMessage.toString(); + //BigInteger plaintext = ciphertext.modPow(d, n); + //return fromHex(plaintext); } + private static BigInteger toHex(String arg) { return new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)); } diff --git a/src/main/java/views/Client.java b/src/main/java/views/Client.java index 3e5c901..e4610ec 100644 --- a/src/main/java/views/Client.java +++ b/src/main/java/views/Client.java @@ -1,14 +1,11 @@ package views; import models.*; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.encrypt.AesBytesEncryptor; -import org.springframework.security.crypto.password.PasswordEncoder; import java.io.*; import java.math.BigInteger; import java.net.Socket; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -16,18 +13,18 @@ import java.util.Arrays; public class Client{ private static Rsa rsa; - private static DataInputStream in; - private static PrintWriter out; + private static BufferedReader in; + private static BufferedWriter out; private static BigInteger se,sn; + private static final String salt = "50726f6653616e736f6e6e65"; public static void connect() throws Exception { //connessione al server e creazione thread client Socket clientSocket = new Socket("localhost", 21324); //Creazione canale di comunicazione Full-Duplex - in = new DataInputStream(clientSocket.getInputStream()); - out = new PrintWriter(clientSocket.getOutputStream(),true); - + in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); //ricezione chiave pubblica del server se = new BigInteger(in.readLine()); @@ -37,25 +34,35 @@ public class Client{ rsa = new Rsa(1024); BigInteger nt = rsa.getN(); BigInteger et = rsa.getE(); + //invio chiave pubblica temporanea al server - out.println(et); - out.println(nt); + send(String.valueOf(et)); + send(String.valueOf(nt)); } - protected static void login() throws IOException, NoSuchAlgorithmException { + protected static void login(String password) throws IOException, NoSuchAlgorithmException { //se le credenziali sono giuste il server invia le chiavi definitive - BigInteger n = new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))); - BigInteger e = new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))); - BigInteger d = new BigInteger(new AesBytesEncryptor("Password", "").decrypt(new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))).toByteArray())); + BigInteger n = new BigInteger(rsa.decrypt(in.readLine())); + BigInteger e = new BigInteger(rsa.decrypt(in.readLine())); + BigInteger d = new BigInteger(new AesBytesEncryptor(password, salt).decrypt(new BigInteger(rsa.decrypt(in.readLine())).toByteArray())); rsa = new Rsa(e, d, n); } - protected static void register() throws NoSuchAlgorithmException, IOException { + protected static void register(String password) throws NoSuchAlgorithmException, IOException { BigInteger d = rsa.getD(); //Invio Username,password e Chiave privata AESata - out.println(new AesBytesEncryptor("Password", "").encrypt(d.toByteArray())); + sendEncrypted(Arrays.toString(new AesBytesEncryptor(password, salt).encrypt(d.toByteArray()))); } + private static void sendEncrypted(String text) throws IOException { + send(rsa.encrypt(text, se, sn)); + } + + public static void send(String message) throws IOException { + out.write(message); + out.newLine(); + out.flush(); + } public static void main(String[] args) throws Exception { connect(); diff --git a/src/main/java/views/ClientReceiveThread.java b/src/main/java/views/ClientReceiveThread.java index 76cafb2..66d275a 100644 --- a/src/main/java/views/ClientReceiveThread.java +++ b/src/main/java/views/ClientReceiveThread.java @@ -2,23 +2,21 @@ package views; import models.Rsa; -import java.io.DataInputStream; +import java.io.BufferedReader; import java.io.IOException; -import java.math.BigInteger; public class ClientReceiveThread extends Thread{ - private static DataInputStream in; - private static Rsa rsa; - public ClientReceiveThread(DataInputStream in, Rsa rsa){ + private final BufferedReader in; + private final Rsa rsa; + public ClientReceiveThread(BufferedReader in, Rsa rsa){ this.in=in; this.rsa=rsa; } public void run() { - while(true){ + while (true){ try { String s = in.readLine(); - System.out.println(s); - System.out.println(rsa.decrypt(new BigInteger(s))); + System.out.print(rsa.decrypt(s)); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/views/ClientSendThread.java b/src/main/java/views/ClientSendThread.java index 85838c9..bc53a1f 100644 --- a/src/main/java/views/ClientSendThread.java +++ b/src/main/java/views/ClientSendThread.java @@ -7,40 +7,41 @@ import java.math.BigInteger; import java.security.NoSuchAlgorithmException; public class ClientSendThread extends Thread{ - private static PrintWriter out; - private static BigInteger se,sn; - private static Rsa rsa; - public ClientSendThread(PrintWriter out,BigInteger se, BigInteger sn,Rsa rsa){ + private final BufferedWriter out; + private final BigInteger se,sn; + private final Rsa rsa; + + public ClientSendThread(BufferedWriter out,BigInteger se, BigInteger sn,Rsa rsa){ this.out = out; this.se = se; this.sn=sn; this.rsa=rsa; } + public void run(){ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - while(true) { + while (true) { try { String s = br.readLine(); - out.println(rsa.encrypt(s, se, sn)); - out.flush(); + send(rsa.encrypt(s, se, sn)); if("REGISTER".equals(s)){ s = br.readLine(); - out.println(rsa.encrypt(s, se, sn)); + send(rsa.encrypt(s, se, sn)); s = br.readLine(); - out.println(rsa.encrypt(s, se, sn)); + send(rsa.encrypt(s, se, sn)); try { - Client.register(); + Client.register(s); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } else if("LOGIN".equals(s)){ s = br.readLine(); - out.println(rsa.encrypt(s, se, sn)); + send(rsa.encrypt(s, se, sn)); s = br.readLine(); - out.println(rsa.encrypt(s, se, sn)); + send(rsa.encrypt(s, se, sn)); try { - Client.login(); + Client.login(s); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } @@ -50,4 +51,10 @@ public class ClientSendThread extends Thread{ } } } + + public void send(String message) throws IOException { + out.write(message); + out.newLine(); + out.flush(); + } }