-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChatServer.java
More file actions
138 lines (114 loc) · 5.27 KB
/
ChatServer.java
File metadata and controls
138 lines (114 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;
import java.security.*;
public class ChatServer {
private static final int PORT = 9000;
public static List<ChatThread> threads = new ArrayList<>();
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
// Set an RSA key pair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server listening on port " + PORT);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New client connected");
// Start a new thread for this client
ChatThread t = new ChatThread(socket , publicKey , privateKey);
threads.add(t);
t.start();
}
}
}
class ChatThread extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private PublicKey clientPublicKey; //The client public key.
private PublicKey serverPublicKey;
private PrivateKey serverPrivateKey;
public ChatThread(Socket socket ,PublicKey key, PrivateKey privateKey) throws IOException {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
serverPublicKey = key;
serverPrivateKey = privateKey;
}
public PublicKey getClientPublicKey() {
return clientPublicKey;
}
public void run() {
try {
// Send a welcome message to the client
out.println("Welcome to the chat server! Type 'BYE' to disconnect.");
// Send the server public key.
String publicKeyStr = serverPublicKey.toString();
String [] arr = publicKeyStr.split("\n");
out.println(arr[2]);
out.println(arr[3]);
// Create a cipher object (will be used to decode the message)
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE , serverPrivateKey);
//get the client public key and modulus
BigInteger clientModulus = new BigInteger(in.readLine().substring(11));
BigInteger clientExpo = new BigInteger(in.readLine().substring(19));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(clientModulus,clientExpo);
clientPublicKey = keyFactory.generatePublic(keySpec);
// Create a cipher object (will be used to encode the message)
Cipher encryptCipher = Cipher.getInstance("RSA");
// Get client messages and broadcast them to all clients
while (true) {
BigInteger input = new BigInteger(in.readLine());
System.out.println("encrypted message: " + input);
byte [] decInput = decryptCipher.doFinal(input.toByteArray());
System.out.println("derypted message:" + new BigInteger(decInput));
String decInputStr = new String(decInput , StandardCharsets.UTF_8);
if (decInputStr == null || decInputStr.substring(decInputStr.length() - 3).equals("BYE")) {
break;
}
for (ChatThread t : ChatServer.threads) {
encryptCipher.init(Cipher.ENCRYPT_MODE , t.getClientPublicKey());
byte [] byteMessage = decInputStr.getBytes(StandardCharsets.UTF_8);
byteMessage = encryptCipher.doFinal(byteMessage);
BigInteger messageNum = new BigInteger(byteMessage);
t.out.println(messageNum);
}
}
} catch (IOException e) {
System.out.println("Error in ChatThread: " + e.getMessage());
} catch (NoSuchPaddingException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException(e);
} catch (BadPaddingException e) {
throw new RuntimeException(e);
} catch (InvalidKeySpecException e) {
throw new RuntimeException(e);
} finally {
try {
out.println("BYE");
System.out.println("User disconnected");
socket.close();
} catch (IOException e) {
}
ChatServer.threads.remove(this);
}
}
}