· 6 years ago · Feb 28, 2019, 06:48 PM
1import javax.crypto.*;
2import javax.crypto.spec.DHParameterSpec;
3import javax.crypto.spec.SecretKeySpec;
4import java.io.*;
5import java.math.BigInteger;
6import java.net.Socket;
7import java.nio.ByteBuffer;
8import java.security.*;
9import java.security.spec.InvalidKeySpecException;
10import java.security.spec.X509EncodedKeySpec;
11
12public class ClientTwo {
13 static int PORT = 11338;
14 static BigInteger g = new BigInteger("129115595377796797872260754286990587373919932143310995152019820961988539107450691898237693336192317366206087177510922095217647062219921553183876476232430921888985287191036474977937325461650715797148343570627272553218190796724095304058885497484176448065844273193302032730583977829212948191249234100369155852168");
15 static BigInteger p = new BigInteger("165599299559711461271372014575825561168377583182463070194199862059444967049140626852928438236366187571526887969259319366449971919367665844413099962594758448603310339244779450534926105586093307455534702963575018551055314397497631095446414992955062052587163874172731570053362641344616087601787442281135614434639");
16 static String hostname = "127.0.0.1";
17 private Cipher decAESsessionCipher;
18 private Cipher encAESsessionCipher;
19
20 public static void main(String[] args){
21 new ClientTwo().run();
22 }
23
24
25 public void run(){
26 DataOutputStream toServer;
27 DataInputStream fromServer;
28
29 try {
30 Thread.sleep(1);
31 Socket server = new Socket(hostname, PORT);
32 toServer = new DataOutputStream(server.getOutputStream());
33 fromServer = new DataInputStream(server.getInputStream());
34
35
36 // Message 1
37 DHParameterSpec dhSpec = new DHParameterSpec(p,g);
38 KeyPairGenerator diffieHellmanGen = KeyPairGenerator.getInstance("DiffieHellman");
39 diffieHellmanGen.initialize(dhSpec);
40 KeyPair serverPair = diffieHellmanGen.generateKeyPair();
41 PrivateKey y = serverPair.getPrivate();
42 PublicKey gToTheY = serverPair.getPublic();
43
44 toServer.writeInt(gToTheY.getEncoded().length);
45 toServer.write(gToTheY.getEncoded());
46
47 System.out.println("sending message1");
48
49 // Message 2
50 int publicKeyLen = fromServer.readInt();
51 byte[] message1 = new byte[publicKeyLen];
52 fromServer.read(message1);
53 KeyFactory keyfactoryDH = KeyFactory.getInstance("DH");
54 X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(message1);
55 PublicKey gToTheX = keyfactoryDH.generatePublic(x509Spec);
56
57 //Calculate session key
58 // This method sets decAESsessionCipher & encAESsessionCipher
59 calculateSessionKey(y, gToTheX);
60 System.out.println("recieving message2");
61
62 // Message 3
63 SecureRandom gen = new SecureRandom();
64 int myNonce = ??????;
65 byte[] myNonceBytes = BigInteger.valueOf(myNonce).toByteArray();
66 byte[] message3ct = encAESsessionCipher.doFinal(myNonceBytes);
67 toServer.write(message3ct);
68 System.out.println("sending message3");
69 System.out.println(byteArrayToHexString(message3ct));
70
71 // Message 4
72 byte[] response = new byte[32];
73 fromServer.read(response);
74 System.out.println("recieving message4");
75
76
77
78 // Message 5
79 byte[] message5 = ????;
80 toServer.write(message5);
81 System.out.println("sending message 5");
82
83
84 // Message 6
85 byte[] secret = new byte[432];
86 fromServer.read(secret);
87 System.out.println("this is the secret");
88 byte[] secretKey = decAESsessionCipher.doFinal(secret);
89
90 System.out.println(new String(secretKey));
91
92 } catch (IOException e) {
93 e.printStackTrace();
94 } catch (NoSuchAlgorithmException e) {
95 e.printStackTrace();
96 } catch (InvalidAlgorithmParameterException e) {
97 e.printStackTrace();
98 } catch (InvalidKeySpecException e) {
99 e.printStackTrace();
100 } catch (BadPaddingException e) {
101 e.printStackTrace();
102 } catch (IllegalBlockSizeException e) {
103 e.printStackTrace();
104 } catch (InterruptedException e){
105 e.printStackTrace();
106 }
107
108
109 }
110 private void calculateSessionKey(PrivateKey y, PublicKey gToTheX) {
111 try {
112 // Find g^xy
113 KeyAgreement serverKeyAgree = KeyAgreement.getInstance("DiffieHellman");
114 serverKeyAgree.init(y);
115 serverKeyAgree.doPhase(gToTheX, true);
116 byte[] secretDH = serverKeyAgree.generateSecret();
117 //Use first 16 bytes of g^xy to make an AES key
118 byte[] aesSecret = new byte[16];
119 System.arraycopy(secretDH,0,aesSecret,0,16);
120 Key aesSessionKey = new SecretKeySpec(aesSecret, "AES");
121 // Set up Cipher Objects
122 decAESsessionCipher = Cipher.getInstance("AES");
123 decAESsessionCipher.init(Cipher.DECRYPT_MODE, aesSessionKey);
124 encAESsessionCipher = Cipher.getInstance("AES");
125 encAESsessionCipher.init(Cipher.ENCRYPT_MODE, aesSessionKey);
126 } catch (NoSuchAlgorithmException e ) {
127 System.out.println(e);
128 } catch (InvalidKeyException e) {
129 System.out.println(e);
130 } catch (NoSuchPaddingException e) {
131 e.printStackTrace();
132 }
133 }
134 private static String byteArrayToHexString(byte[] data) {
135 StringBuffer buf = new StringBuffer();
136 for (int i = 0; i < data.length; i++) {
137 int halfbyte = (data[i] >>> 4) & 0x0F;
138 int two_halfs = 0;
139 do {
140 if ((0 <= halfbyte) && (halfbyte <= 9))
141 buf.append((char) ('0' + halfbyte));
142 else
143 buf.append((char) ('a' + (halfbyte - 10)));
144 halfbyte = data[i] & 0x0F;
145 } while(two_halfs++ < 1);
146 }
147 return buf.toString();
148 }
149 private static int fromByteArray(byte[] bytes) {
150 return ByteBuffer.wrap(bytes).getInt();
151 }
152 private static byte[] toByteArray(int value) {
153 return new byte[] {
154 (byte)(value >> 24),
155 (byte)(value >> 16),
156 (byte)(value >> 8),
157 (byte)value };
158 }
159}