· 5 years ago · Mar 23, 2020, 07:54 PM
1import java.net.*;
2import java.io.*;
3import javax.crypto.*;
4import javax.crypto.spec.IvParameterSpec;
5import javax.crypto.spec.SecretKeySpec;
6import java.security.*;
7
8public class Client {
9 public static void main(String args[]) {
10
11 Socket s = null;
12 int serversocket = 4567;
13 try {
14 s = new Socket("127.0.0.1", serversocket);
15
16 DataInputStream in = new DataInputStream(s.getInputStream());
17 DataOutputStream out = new DataOutputStream(s.getOutputStream());
18
19 while (true){
20 //key
21 byte [] key = {1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4};
22
23 //hash function and new keys
24 MessageDigest md = MessageDigest.getInstance("SHA-256");
25
26 byte [] byte1 = {1};
27 byte [] aux1 = concat(key, byte1);
28 byte [] hash1= md.digest(aux1);
29 SecretKey k1 = new SecretKeySpec(hash1, 0, hash1.length, "AES");
30
31 byte [] byte2 = {2};
32 byte [] aux2 = concat(key, byte2);
33 byte [] hash2= md.digest(aux2);
34 SecretKey k2 = new SecretKeySpec(hash2, 0, hash2.length, "HMAC");
35
36 //message authentication code
37 Mac mac = Mac.getInstance("HmacSHA256");
38 mac.init(k2);
39 int nSeq = 0;
40
41 //nonce - sends the bytes in plaintext so that the server can create the same IV
42 byte[] bytesForIV=new byte[16];
43 SecureRandom sr = new SecureRandom();
44 sr.nextBytes(bytesForIV);
45 IvParameterSpec iv = new IvParameterSpec(bytesForIV);
46 out.write(bytesForIV);
47
48 //E(m, k1) = c
49 Cipher c = Cipher.getInstance("AES/CTR/PKCS5Padding");
50 c.init(Cipher.ENCRYPT_MODE, k1, iv);
51 String text = "";
52 InputStreamReader input = new InputStreamReader(System.in);
53 BufferedReader reader = new BufferedReader(input);
54 while (true) {
55 try {
56 text = reader.readLine();
57 }
58 catch (Exception e) {}
59
60 byte [] enc = c.doFinal(text.getBytes());
61 byte [] nSeqByte = intToByteArray(nSeq);
62 byte [] authTagAux = concat(enc, nSeqByte);
63 byte [] authTag = mac.doFinal(authTagAux);
64 out.write(authTag);
65 out.write("\n".getBytes());
66 out.write(enc);
67 nSeq++;
68 }
69 }
70 } catch (UnknownHostException e) {
71 System.out.println("Sock:" + e.getMessage());
72 } catch (EOFException e) {
73 System.out.println("EOF:" + e.getMessage());
74 } catch (IOException e) {
75 System.out.println("IO:" + e.getMessage());
76 } catch (NoSuchPaddingException e) {
77 e.printStackTrace();
78 } catch (NoSuchAlgorithmException e) {
79 e.printStackTrace();
80 } catch (InvalidAlgorithmParameterException e) {
81 e.printStackTrace();
82 } catch (InvalidKeyException e) {
83 e.printStackTrace();
84 } catch (BadPaddingException e) {
85 e.printStackTrace();
86 } catch (IllegalBlockSizeException e) {
87 e.printStackTrace();
88 } finally {
89 if (s != null)
90 try {
91 s.close();
92 } catch (IOException e) {
93 System.out.println("close:" + e.getMessage());
94 }
95 }
96 }
97
98 private static byte [] concat(byte[] first, byte[] second) throws IOException {
99 ByteArrayOutputStream baos = new ByteArrayOutputStream();
100 baos.write(first);
101 baos.write(second);
102 byte [] result = baos.toByteArray();
103 baos.reset();
104 return result;
105 }
106
107 //https://stackoverflow.com/questions/2183240/java-integer-to-byte-array
108 public static final byte[] intToByteArray(int value) {
109 return new byte[]{
110 (byte)(value >>> 24),
111 (byte)(value >>> 16),
112 (byte)(value >>> 8),
113 (byte)value};
114 }
115}