* added desktop client

Signed-off-by: CubeBit <denis-seredenko@ukr.net>
This commit is contained in:
2023-08-03 19:08:19 +02:00
parent 3b6d18a83b
commit 590b989b1b
8 changed files with 41 additions and 47 deletions

View File

@@ -44,20 +44,17 @@ public class ClientThread implements Runnable {
if (prefix.equals("RSA") && !rsaReceived) { if (prefix.equals("RSA") && !rsaReceived) {
Client.serverPublicRSA = EncryptionUtil.stringToPublicKey(restMessage); Client.serverPublicRSA = EncryptionUtil.stringToPublicKey(restMessage);
rsaReceived = true; rsaReceived = true;
continue;
} }
if (prefix.equals("AES") && !aesReceived) { if (prefix.equals("AES") && !aesReceived) {
String decryptedAES = EncryptionUtil.decryptWithRSA(restMessage, Client.keys.getPrivate()); String decryptedAES = EncryptionUtil.decryptWithRSA(restMessage, Client.keys.getPrivate());
Client.aesKey = EncryptionUtil.aesKeyFromString(decryptedAES); Client.aesKey = EncryptionUtil.aesKeyFromString(decryptedAES);
aesReceived = true; aesReceived = true;
continue;
} }
if (prefix.equals("IVK")) { if (prefix.equals("IVK")) {
String decryptedIVKey = EncryptionUtil.decryptWithRSA(restMessage, Client.keys.getPrivate()); String decryptedIVKey = EncryptionUtil.decryptWithRSA(restMessage, Client.keys.getPrivate());
Client.ivKey = EncryptionUtil.ivKeyFromString(decryptedIVKey); Client.ivKey = EncryptionUtil.ivKeyFromString(decryptedIVKey);
continue;
} }
if (prefix.equals("TXT") && aesReceived && rsaReceived) { if (prefix.equals("TXT") && aesReceived && rsaReceived) {

View File

@@ -53,7 +53,7 @@
<configuration> <configuration>
<jlinkImageName>hellofx</jlinkImageName> <jlinkImageName>hellofx</jlinkImageName>
<launcher>securedChat</launcher> <launcher>securedChat</launcher>
<mainClass>org.orinprojects.desktop.Main</mainClass> <mainClass>org.orinprojects.desktop.DesktopClient</mainClass>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@@ -1,8 +1,8 @@
package org.orinprojects.desktop; package org.orinprojects.desktop;
import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
@@ -20,8 +20,8 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import static org.orinprojects.desktop.Main.aesKey; import static org.orinprojects.desktop.DesktopClient.aesKey;
import static org.orinprojects.desktop.Main.keys; import static org.orinprojects.desktop.DesktopClient.keys;
public class ChatController { public class ChatController {
@@ -90,11 +90,13 @@ public class ChatController {
} }
public void sendMessage() throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { public void sendMessage() throws IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
if (!clientThread.aesReceived && !clientThread.rsaReceived) if (!clientThread.aesReceived && !clientThread.rsaReceived) {
System.out.println("Wait for complete initialisation!"); Alert alert = new Alert(Alert.AlertType.WARNING, "Wait for complete initialisation!");
alert.showAndWait();
}
if (clientThread.rsaReceived && clientThread.aesReceived) { if (clientThread.rsaReceived && clientThread.aesReceived) {
String encryptedText = EncryptionUtil.encryptWithAES(messageTextInput.getText(), aesKey, Main.ivKey); String encryptedText = EncryptionUtil.encryptWithAES(messageTextInput.getText(), aesKey, DesktopClient.ivKey);
clientThread.out.println("TXT" + encryptedText); clientThread.out.println("TXT" + encryptedText);
clientThread.out.flush(); clientThread.out.flush();
} }

View File

@@ -2,6 +2,7 @@ package org.orinprojects.desktop;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.text.Font; import javafx.scene.text.Font;
@@ -33,6 +34,8 @@ public class ClientThread implements Runnable {
boolean aesReceived = false; boolean aesReceived = false;
private boolean running = true;
Text messageExample; Text messageExample;
VBox messagesBox; VBox messagesBox;
@@ -47,33 +50,30 @@ public class ClientThread implements Runnable {
@Override @Override
public void run() { public void run() {
while (clientSocket.isConnected()) { while (clientSocket.isConnected() && running) {
try { try {
String receivedMessage = in.readLine(); String receivedMessage = in.readLine();
String prefix = receivedMessage.substring(0, 3); String prefix = receivedMessage.substring(0, 3);
String restMessage = receivedMessage.substring(3); String restMessage = receivedMessage.substring(3);
if (prefix.equals("RSA") && !rsaReceived) { if (prefix.equals("RSA") && !rsaReceived) {
Main.serverPublicRSA = EncryptionUtil.stringToPublicKey(restMessage); DesktopClient.serverPublicRSA = EncryptionUtil.stringToPublicKey(restMessage);
rsaReceived = true; rsaReceived = true;
continue;
} }
if (prefix.equals("AES") && !aesReceived) { if (prefix.equals("AES") && !aesReceived) {
String decryptedAES = EncryptionUtil.decryptWithRSA(restMessage, Main.keys.getPrivate()); String decryptedAES = EncryptionUtil.decryptWithRSA(restMessage, DesktopClient.keys.getPrivate());
Main.aesKey = EncryptionUtil.aesKeyFromString(decryptedAES); DesktopClient.aesKey = EncryptionUtil.aesKeyFromString(decryptedAES);
aesReceived = true; aesReceived = true;
continue;
} }
if (prefix.equals("IVK")) { if (prefix.equals("IVK")) {
String decryptedIVKey = EncryptionUtil.decryptWithRSA(restMessage, Main.keys.getPrivate()); String decryptedIVKey = EncryptionUtil.decryptWithRSA(restMessage, DesktopClient.keys.getPrivate());
Main.ivKey = EncryptionUtil.ivKeyFromString(decryptedIVKey); DesktopClient.ivKey = EncryptionUtil.ivKeyFromString(decryptedIVKey);
continue;
} }
if (prefix.equals("TXT") && aesReceived && rsaReceived) { if (prefix.equals("TXT") && aesReceived && rsaReceived) {
String decryptedMessage = EncryptionUtil.decryptWithAES(restMessage, Main.aesKey, Main.ivKey); String decryptedMessage = EncryptionUtil.decryptWithAES(restMessage, DesktopClient.aesKey, DesktopClient.ivKey);
Label text = new Label(decryptedMessage); Label text = new Label(decryptedMessage);
text.setFont(new Font(14)); text.setFont(new Font(14));
@@ -83,8 +83,12 @@ public class ClientThread implements Runnable {
} }
} catch (NoSuchPaddingException | IllegalBlockSizeException | IOException | NoSuchAlgorithmException | } catch (NoSuchPaddingException | IllegalBlockSizeException | IOException | NoSuchAlgorithmException |
InvalidKeySpecException | BadPaddingException |InvalidKeyException | InvalidAlgorithmParameterException e) { InvalidKeySpecException | BadPaddingException |InvalidKeyException | InvalidAlgorithmParameterException e) {
System.err.println("Disconnected from server!"); Platform.runLater(() -> {
System.exit(-1); Alert alert = new Alert(Alert.AlertType.ERROR, "Disconnected from server!");
alert.show();
});
running = false;
closeAllConnections(clientSocket, in, out); closeAllConnections(clientSocket, in, out);
} }
} }

View File

@@ -13,10 +13,7 @@ import java.security.KeyPair;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PublicKey; import java.security.PublicKey;
/** public class DesktopClient extends Application {
* JavaFX App
*/
public class Main extends Application {
static KeyPair keys; static KeyPair keys;

View File

@@ -63,18 +63,15 @@ public class ClientHandler implements Runnable {
out.flush(); out.flush();
aesSent = true; aesSent = true;
continue;
} }
if (prefix.equals("WLC")) { if (prefix.equals("WLC")) {
this.username = restMessage; this.username = restMessage;
//TODO: add better logic if (Server.clientKeys.get(username) != null) {
// if (Server.clientKeys.get(username) != null) { in.close();
// in.close(); out.close();
// out.close(); clientSocket.close();
// clientSocket.close(); }
// }
continue;
} }
if (prefix.equals("TXT") && rsaReceived && aesSent) { if (prefix.equals("TXT") && rsaReceived && aesSent) {

View File

@@ -31,14 +31,14 @@ public class Server {
static byte[] ivKey; static byte[] ivKey;
public static void main(String[] args) throws IOException, ArgumentsException, NoSuchAlgorithmException { public static void main(String[] args) throws ArgumentsException, NoSuchAlgorithmException, IOException {
Server.serverKeys = EncryptionUtil.generateRSAKeys(); Server.serverKeys = EncryptionUtil.generateRSAKeys();
Server.ivKey = EncryptionUtil.generateIV(); Server.ivKey = EncryptionUtil.generateIV();
Server.aesKey = EncryptionUtil.generateAESKey(); Server.aesKey = EncryptionUtil.generateAESKey();
int portNumber = getPortNumber(args); int portNumber = getPortNumber(args);
ServerSocket server = new ServerSocket(portNumber); try (ServerSocket server = new ServerSocket(portNumber)) {
while (!server.isClosed()) { while (!server.isClosed()) {
Socket clientSocket = server.accept(); Socket clientSocket = server.accept();
@@ -48,6 +48,7 @@ public class Server {
executor.execute(clientHandler); executor.execute(clientHandler);
} }
} }
}
private static int getPortNumber(String[] args) throws ArgumentsException { private static int getPortNumber(String[] args) throws ArgumentsException {
if (args.length != 2) if (args.length != 2)

View File

@@ -87,28 +87,24 @@ public class EncryptionUtil {
} }
public static String encryptWithAES(String plainText, SecretKey aesKey, byte[] ivKey) throws IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { public static String encryptWithAES(String plainText, SecretKey aesKey, byte[] ivKey) throws IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
Cipher aesChiper = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey.getEncoded(), "AES"); SecretKeySpec keySpec = new SecretKeySpec(aesKey.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, ivKey); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, ivKey);
Cipher aesChiper = Cipher.getInstance("AES/GCM/NoPadding");
aesChiper.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec); aesChiper.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec);
byte[] byteCipherText = aesChiper.doFinal(plainText.getBytes()); byte[] byteCipherText = aesChiper.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(byteCipherText); return Base64.getEncoder().encodeToString(byteCipherText);
} }
public static String decryptWithAES(String encryptedMessage, SecretKey aesKey, byte[] ivKey) throws IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException { public static String decryptWithAES(String encryptedMessage, SecretKey aesKey, byte[] ivKey) throws IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
Cipher aesChiper = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey.getEncoded(), "AES"); SecretKeySpec keySpec = new SecretKeySpec(aesKey.getEncoded(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, ivKey); GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, ivKey);
Cipher aesChiper = Cipher.getInstance("AES/GCM/NoPadding");
aesChiper.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec); aesChiper.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
byte[] byteCipherText = aesChiper.doFinal(Base64.getDecoder().decode(encryptedMessage)); byte[] byteCipherText = aesChiper.doFinal(Base64.getDecoder().decode(encryptedMessage));
return new String(byteCipherText); return new String(byteCipherText);
} }