· 5 years ago · Mar 30, 2020, 10:50 PM
1import java.net.*;
2import java.io.*;
3import javax.crypto.*;
4import javax.crypto.spec.IvParameterSpec;
5import javax.crypto.spec.SecretKeySpec;
6import java.security.InvalidAlgorithmParameterException;
7import java.security.InvalidKeyException;
8import java.security.MessageDigest;
9import java.security.NoSuchAlgorithmException;
10import java.util.Arrays;
11
12public class Server{
13 public static void main(String args[]){
14 int number=0;
15 try{
16 int serverPort = 4567;
17 ServerSocket listenSocket = new ServerSocket(serverPort);
18 while(true) {
19 Socket clientSocket = listenSocket.accept();
20 new Connection(clientSocket,number);
21 number++;
22 }
23 } catch(IOException e) {
24 System.out.println("Listen:" + e.getMessage());
25 }
26 }
27}
28
29class Connection extends Thread {
30 DataInputStream in;
31 DataOutputStream out;
32 Socket clientSocket;
33 int number;
34 int stopped;
35
36 public Connection (Socket aClientSocket,int clientNumber) {
37 try{
38 number=clientNumber;
39 clientSocket = aClientSocket;
40 in = new DataInputStream(clientSocket.getInputStream());
41 out = new DataOutputStream(clientSocket.getOutputStream());
42 stopped=0;
43 this.start();
44 }catch(IOException e){System.out.println("Connection:" + e.getMessage());}
45 }
46
47 public void run(){
48 try{
49 while(true){
50 //key
51 byte [] key = {1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
52
53 //hash function and new keys
54 MessageDigest md = MessageDigest.getInstance("SHA-256");
55
56 byte [] byte1 = {1};
57 byte [] aux1 = concat(key, byte1);
58 byte [] hash1= md.digest(aux1);
59 SecretKey k1 = new SecretKeySpec(hash1, 0, hash1.length, "AES");
60
61 byte [] byte2 = {2};
62 byte [] aux2 = concat(key, byte2);
63 byte [] hash2= md.digest(aux2);
64 SecretKey k2 = new SecretKeySpec(hash2, 0, hash2.length, "AES");
65
66 //message authentication code
67 Mac mac = Mac.getInstance("HmacSHA256");
68 mac.init(k2);
69 int nSeq = 0;
70
71 //nonce - receives IV in plaintext
72 byte[] nonce=new byte[16];
73 in.read(nonce);
74 IvParameterSpec iv = new IvParameterSpec(nonce);
75
76 //D(m, k1) = c - c is only decrypted if the macs match
77 Cipher c = Cipher.getInstance("AES/CTR/PKCS5Padding");
78 c.init(Cipher.DECRYPT_MODE, k1, iv);
79 int text;
80
81 while (stopped!=1){
82 try{
83 //size of the ciphertext
84 byte sizeInBytes[] = new byte[4];
85
86 if(in.read(sizeInBytes)!=-1){
87 int size=convertByteToInt(sizeInBytes);
88
89 //256 bits represent the mac
90 byte authTagClient[] = new byte[32];
91 in.read(authTagClient);
92
93 //ciphertext
94 byte ciphertext[] = new byte[size];
95 in.read(ciphertext);
96
97 //calculates the server authentication tag
98 byte [] nSeqByte = intToByteArray(nSeq);
99 byte [] authTagAux = concat(ciphertext, nSeqByte);
100 byte [] authTag = mac.doFinal(authTagAux);
101
102 if(Arrays.equals(authTagClient, authTag)){
103 byte [] dec=c.doFinal(ciphertext);
104 System.out.println("Text from client : "+new String (dec));
105 }
106 else{
107 System.out.println("Invalid MAC");
108 }
109 nSeq++;
110 }else{
111 stopped=1;
112 }
113 }
114 catch (IOException e) {
115 }
116 }
117
118 }
119 }
120 catch (NoSuchPaddingException e) {
121 e.printStackTrace();
122 }
123
124 catch (NoSuchAlgorithmException e) {
125 e.printStackTrace();
126 }
127 catch (InvalidKeyException e) {
128 e.printStackTrace();
129 }
130 catch (InvalidAlgorithmParameterException e) {
131 e.printStackTrace();
132 } catch (BadPaddingException e) {
133 e.printStackTrace();
134 } catch (IllegalBlockSizeException e) {
135 e.printStackTrace();
136 } catch (IOException e) {
137 e.printStackTrace();
138 }
139 }
140
141 private byte [] concat(byte[] first, byte[] second) throws IOException {
142 ByteArrayOutputStream baos = new ByteArrayOutputStream();
143 baos.write(first);
144 baos.write(second);
145 byte [] result = baos.toByteArray();
146 baos.reset();
147 return result;
148 }
149
150 //https://stackoverflow.com/questions/2183240/java-integer-to-byte-array
151 public static final byte[] intToByteArray(int value) {
152 return new byte[]{
153 (byte)(value >>> 24),
154 (byte)(value >>> 16),
155 (byte)(value >>> 8),
156 (byte)value};
157 }
158
159 //https://stackoverflow.com/questions/4950598/convert-byte-to-int
160 public int convertByteToInt(byte[] b)
161 {
162 int value= 0;
163 for(int i=0; i<b.length; i++)
164 value = (value << 8) | b[i];
165 return value;
166 }
167}