· 5 years ago · Mar 24, 2020, 06:24 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 - só se decifra se a autenticação do mac correr bem
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
83 try{
84 byte sizeInBytes[] = new byte[4]; // le 4 bytes que dizem o tamanho do pacote
85
86 if(in.read(sizeInBytes)!=-1){ // se nao houver mais nada para ler acaba
87
88
89
90 int size=convertByteToInt(sizeInBytes);
91 //System.out.println("size : "+size);
92
93 byte authTagClient[] = new byte[32]; // le 256 bits do mac
94 in.read(authTagClient);
95
96
97 byte enc[] = new byte[size]; // le o ciphertext
98 in.read(enc);
99
100
101 byte [] nSeqByte = intToByteArray(nSeq);
102 byte [] authTagAux = concat(enc, nSeqByte);
103 byte [] authTag = mac.doFinal(authTagAux);
104
105 if(Arrays.equals(authTagClient, authTag)){
106 byte [] dec=c.doFinal(enc);
107 System.out.println("Text from client : "+new String (dec));
108 }
109 else{
110 System.out.println("Invalid MAC");
111 }
112
113 nSeq++;
114 }else{
115 stopped=1;
116 }
117
118 }
119 catch (IOException e) {
120 }
121 }
122
123 }
124 }
125 catch (NoSuchPaddingException e) {
126 e.printStackTrace();
127 }
128
129 catch (NoSuchAlgorithmException e) {
130 e.printStackTrace();
131 }
132 catch (InvalidKeyException e) {
133 e.printStackTrace();
134 }
135 catch (InvalidAlgorithmParameterException e) {
136 e.printStackTrace();
137 } catch (BadPaddingException e) {
138 e.printStackTrace();
139 } catch (IllegalBlockSizeException e) {
140 e.printStackTrace();
141 } catch (IOException e) {
142 e.printStackTrace();
143 }
144 }
145
146 private byte [] concat(byte[] first, byte[] second) throws IOException {
147 ByteArrayOutputStream baos = new ByteArrayOutputStream();
148 baos.write(first);
149 baos.write(second);
150 byte [] result = baos.toByteArray();
151 baos.reset();
152 return result;
153 }
154
155 //https://stackoverflow.com/questions/2183240/java-integer-to-byte-array
156 public static final byte[] intToByteArray(int value) {
157 return new byte[]{
158 (byte)(value >>> 24),
159 (byte)(value >>> 16),
160 (byte)(value >>> 8),
161 (byte)value};
162 }
163
164 //https://stackoverflow.com/questions/4950598/convert-byte-to-int
165 public int convertByteToInt(byte[] b)
166 {
167 int value= 0;
168 for(int i=0; i<b.length; i++)
169 value = (value << 8) | b[i];
170 return value;
171 }
172}