* added desktop client
Signed-off-by: CubeBit <denis-seredenko@ukr.net>
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user