Fixed bigger messages bug, added working login and register, other smaller fixes

This commit is contained in:
Mariano Riefolo 2024-04-08 17:47:34 +02:00
parent 4588be4d74
commit 68ff067a5e
6 changed files with 134 additions and 66 deletions

View File

@ -1,5 +1,6 @@
package controllers; package controllers;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -14,7 +15,7 @@ public class MessageForwarder {
idThread.put(id, thread); 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); idThread.get(id).sendMessage(message, senderId);
} }
} }

View File

@ -13,7 +13,7 @@ import static controllers.Database.registerAccount;
public class ServerThread extends Thread { public class ServerThread extends Thread {
private final Socket client; private final Socket client;
private BufferedReader fromClient; private BufferedReader fromClient;
private PrintWriter toClient; private BufferedWriter toClient;
private final Rsa rsa; private final Rsa rsa;
private BigInteger clientE, clientN; private BigInteger clientE, clientN;
private int clientId; private int clientId;
@ -26,13 +26,21 @@ public class ServerThread extends Thread {
public void run() { public void run() {
try { try {
fromClient = new BufferedReader(new InputStreamReader(client.getInputStream())); fromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
toClient = new PrintWriter(client.getOutputStream(),true); toClient = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
toClient.println(rsa.getE().toString()); try {
toClient.println(rsa.getN().toString()); send(rsa.getE().toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
send(rsa.getN().toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
try { try {
clientE = new BigInteger(fromClient.readLine()); clientE = new BigInteger(fromClient.readLine());
@ -43,8 +51,9 @@ public class ServerThread extends Thread {
for (;;) { for (;;) {
String operation; String operation;
sendEncrypted("Quale operazione vuoi effettuare? (REGISTER|LOGIN): ");
try { try {
operation = rsa.decrypt(new BigInteger(fromClient.readLine())); operation = rsa.decrypt(fromClient.readLine());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -52,10 +61,10 @@ public class ServerThread extends Thread {
String username, password; String username, password;
try { try {
toClient.print("Inserisci l'username: "); sendEncrypted("Inserisci l'username: ");
username = rsa.decrypt(new BigInteger(fromClient.readLine())); username = rsa.decrypt(fromClient.readLine());
toClient.print("Inserisci la password: "); sendEncrypted("Inserisci la password: ");
password = rsa.decrypt(new BigInteger(fromClient.readLine())); password = rsa.decrypt(fromClient.readLine());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -64,19 +73,23 @@ public class ServerThread extends Thread {
if ("LOGIN".equals(operation)) { if ("LOGIN".equals(operation)) {
if (login(username, password)) { if (login(username, password)) {
Account account = getAccount(username, password); Account account = getAccount(username, password);
toClient.println(rsa.encrypt(String.valueOf(account.n()), clientE, clientN).toString()); if (account == null) {
toClient.println(rsa.encrypt(String.valueOf(account.d()), clientE, clientN).toString()); sendEncrypted("FAIL");
toClient.println(rsa.encrypt(String.valueOf(account.e()), clientE, clientN).toString()); break;
toClient.println(rsa.encrypt("SUCCESS", clientE, clientN).toString()); }
sendEncrypted(String.valueOf(account.n()));
sendEncrypted(String.valueOf(account.e()));
sendEncrypted(String.valueOf(account.d()));
sendEncrypted("SUCCESS");
break; break;
} }
} else if ("REGISTER".equals(operation)) { } else if ("REGISTER".equals(operation)) {
if (register(username, password)) { if (register(username, password)) {
toClient.println(rsa.encrypt("SUCCESS", clientE, clientN).toString()); sendEncrypted("SUCCESS");
break; break;
} }
} else { } else {
toClient.println(rsa.encrypt("FAIL", clientE, clientN).toString()); sendEncrypted("FAIL");
} }
} }
@ -87,17 +100,35 @@ public class ServerThread extends Thread {
for (;;) { for (;;) {
try { try {
recipientId = Integer.parseInt(rsa.decrypt(new BigInteger(fromClient.readLine()))); recipientId = Integer.parseInt(rsa.decrypt(fromClient.readLine()));
message = rsa.decrypt(new BigInteger(fromClient.readLine())); message = rsa.decrypt(fromClient.readLine());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
if (message == null || "DISCONNECT".equals(message)) break; if (message == null || "DISCONNECT".equals(message)) break;
try {
MessageForwarder.sendTo(recipientId, message, clientId); 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) { private boolean login(String username, String password) {
Account account = getAccount(username, password); Account account = getAccount(username, password);
@ -119,9 +150,9 @@ public class ServerThread extends Thread {
return clientId != -1; return clientId != -1;
} }
public void sendMessage(String message, int sender) { public void sendMessage(String message, int sender) throws IOException {
toClient.println("INCOMING"); send("INCOMING");
toClient.println(sender); send(String.valueOf(sender));
toClient.println(message); send(message);
} }
} }

View File

@ -6,6 +6,7 @@ import java.security.SecureRandom;
public class Rsa { public class Rsa {
private final BigInteger e, d, n; private final BigInteger e, d, n;
private static final int CHUNK_SIZE = 64;
public Rsa(int numberOfBytes) { public Rsa(int numberOfBytes) {
BigInteger p = generatePrime(numberOfBytes); BigInteger p = generatePrime(numberOfBytes);
@ -29,16 +30,39 @@ public class Rsa {
return new BigInteger(numberOfBytes, 100, secureRandom).nextProbablePrime(); return new BigInteger(numberOfBytes, 100, secureRandom).nextProbablePrime();
} }
public BigInteger encrypt(String message, BigInteger e, BigInteger n) { public String encrypt(String message, BigInteger e, BigInteger n) {
BigInteger plaintext = toHex(message); StringBuilder encryptedMessage = new StringBuilder();
return plaintext.modPow(e, n);
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("|");
} }
public String decrypt(BigInteger ciphertext) { return encryptedMessage.toString();
BigInteger plaintext = ciphertext.modPow(d, n); //BigInteger plaintext = toHex(message);
return fromHex(plaintext); //return plaintext.modPow(e, n);
} }
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) { private static BigInteger toHex(String arg) {
return new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8)); return new BigInteger(1, arg.getBytes(StandardCharsets.UTF_8));
} }

View File

@ -1,14 +1,11 @@
package views; package views;
import models.*; import models.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.encrypt.AesBytesEncryptor; import org.springframework.security.crypto.encrypt.AesBytesEncryptor;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.io.*; import java.io.*;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.Socket; import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
@ -16,18 +13,18 @@ import java.util.Arrays;
public class Client{ public class Client{
private static Rsa rsa; private static Rsa rsa;
private static DataInputStream in; private static BufferedReader in;
private static PrintWriter out; private static BufferedWriter out;
private static BigInteger se,sn; private static BigInteger se,sn;
private static final String salt = "50726f6653616e736f6e6e65";
public static void connect() throws Exception { public static void connect() throws Exception {
//connessione al server e creazione thread client //connessione al server e creazione thread client
Socket clientSocket = new Socket("localhost", 21324); Socket clientSocket = new Socket("localhost", 21324);
//Creazione canale di comunicazione Full-Duplex //Creazione canale di comunicazione Full-Duplex
in = new DataInputStream(clientSocket.getInputStream()); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(),true); out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
//ricezione chiave pubblica del server //ricezione chiave pubblica del server
se = new BigInteger(in.readLine()); se = new BigInteger(in.readLine());
@ -37,25 +34,35 @@ public class Client{
rsa = new Rsa(1024); rsa = new Rsa(1024);
BigInteger nt = rsa.getN(); BigInteger nt = rsa.getN();
BigInteger et = rsa.getE(); BigInteger et = rsa.getE();
//invio chiave pubblica temporanea al server //invio chiave pubblica temporanea al server
out.println(et); send(String.valueOf(et));
out.println(nt); 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 //se le credenziali sono giuste il server invia le chiavi definitive
BigInteger n = new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))); BigInteger n = new BigInteger(rsa.decrypt(in.readLine()));
BigInteger e = new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))); BigInteger e = new BigInteger(rsa.decrypt(in.readLine()));
BigInteger d = new BigInteger(new AesBytesEncryptor("Password", "").decrypt(new BigInteger(rsa.decrypt(new BigInteger(in.readLine()))).toByteArray())); BigInteger d = new BigInteger(new AesBytesEncryptor(password, salt).decrypt(new BigInteger(rsa.decrypt(in.readLine())).toByteArray()));
rsa = new Rsa(e, d, n); 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(); BigInteger d = rsa.getD();
//Invio Username,password e Chiave privata AESata //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 { public static void main(String[] args) throws Exception {
connect(); connect();

View File

@ -2,23 +2,21 @@ package views;
import models.Rsa; import models.Rsa;
import java.io.DataInputStream; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger;
public class ClientReceiveThread extends Thread{ public class ClientReceiveThread extends Thread{
private static DataInputStream in; private final BufferedReader in;
private static Rsa rsa; private final Rsa rsa;
public ClientReceiveThread(DataInputStream in, Rsa rsa){ public ClientReceiveThread(BufferedReader in, Rsa rsa){
this.in=in; this.in=in;
this.rsa=rsa; this.rsa=rsa;
} }
public void run() { public void run() {
while(true){ while (true){
try { try {
String s = in.readLine(); String s = in.readLine();
System.out.println(s); System.out.print(rsa.decrypt(s));
System.out.println(rsa.decrypt(new BigInteger(s)));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -7,40 +7,41 @@ import java.math.BigInteger;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
public class ClientSendThread extends Thread{ public class ClientSendThread extends Thread{
private static PrintWriter out; private final BufferedWriter out;
private static BigInteger se,sn; private final BigInteger se,sn;
private static Rsa rsa; private final Rsa rsa;
public ClientSendThread(PrintWriter out,BigInteger se, BigInteger sn,Rsa rsa){
public ClientSendThread(BufferedWriter out,BigInteger se, BigInteger sn,Rsa rsa){
this.out = out; this.out = out;
this.se = se; this.se = se;
this.sn=sn; this.sn=sn;
this.rsa=rsa; this.rsa=rsa;
} }
public void run(){ public void run(){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true) { while (true) {
try { try {
String s = br.readLine(); String s = br.readLine();
out.println(rsa.encrypt(s, se, sn)); send(rsa.encrypt(s, se, sn));
out.flush();
if("REGISTER".equals(s)){ if("REGISTER".equals(s)){
s = br.readLine(); s = br.readLine();
out.println(rsa.encrypt(s, se, sn)); send(rsa.encrypt(s, se, sn));
s = br.readLine(); s = br.readLine();
out.println(rsa.encrypt(s, se, sn)); send(rsa.encrypt(s, se, sn));
try { try {
Client.register(); Client.register(s);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
else if("LOGIN".equals(s)){ else if("LOGIN".equals(s)){
s = br.readLine(); s = br.readLine();
out.println(rsa.encrypt(s, se, sn)); send(rsa.encrypt(s, se, sn));
s = br.readLine(); s = br.readLine();
out.println(rsa.encrypt(s, se, sn)); send(rsa.encrypt(s, se, sn));
try { try {
Client.login(); Client.login(s);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new RuntimeException(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();
}
} }