· 5 years ago · Sep 15, 2020, 10:20 AM
1package com.example.bos3;
2
3import androidx.appcompat.app.AppCompatActivity;
4
5import android.os.Bundle;
6import android.widget.EditText;
7import android.widget.TextView;
8
9import android.view.View;
10import android.widget.Button;
11
12import java.io.BufferedReader;
13import java.io.IOException;
14import java.io.InputStreamReader;
15import java.io.OutputStream;
16import java.io.InputStream;
17import java.io.PrintWriter;
18import java.net.Socket;
19import java.nio.*;
20import java.nio.charset.Charset;
21import java.security.*;
22import java.security.spec.*;
23import javax.crypto.spec.*;
24import javax.crypto.*;
25
26import android.util.Base64;
27
28public class MainActivity extends AppCompatActivity {
29
30 Thread Thread1 = null;
31 EditText serverIP, serverPort;
32 EditText userMessage;
33 TextView chatMessages;
34 Button btnSend;
35 Thread ThreadConnect = null;
36
37 String SERVER_IP;
38 int SERVER_PORT;
39
40 InputStream in_stream;
41 OutputStream soc_out_stream;
42 Cipher cipher;
43 Cipher cipher_d;
44 Cipher cipher_rsa;
45
46 @Override
47 protected void onCreate(Bundle savedInstanceState) {
48 super.onCreate(savedInstanceState);
49 setContentView(R.layout.activity_main);
50
51 serverIP = findViewById(R.id.editIp);
52 serverPort = findViewById(R.id.editPort);
53
54 // Значения по умолчанию
55 serverIP.setText("10.0.2.2"); // Вместо 127.0.0.1 используем этот адрес
56 serverPort.setText("9001");
57
58
59 chatMessages = findViewById(R.id.chatId);
60 userMessage = findViewById(R.id.userMsg);
61 btnSend = findViewById(R.id.btnSend);
62
63 Button btnConnect = findViewById(R.id.btnConnect);
64 btnConnect.setOnClickListener(new View.OnClickListener() {
65 @Override
66 public void onClick(View v) {
67 chatMessages.setText("");
68 SERVER_IP = serverIP.getText().toString().trim();
69 SERVER_PORT = Integer.parseInt(serverPort.getText().toString().trim());
70 Thread ThreadConnect = new Thread(new ThreadConnect());
71 ThreadConnect.start();
72 }
73 });
74
75 Button btnSend = findViewById(R.id.btnSend);
76 btnSend.setOnClickListener(new View.OnClickListener() {
77 @Override
78 public void onClick(View v) {
79 String userMsg = userMessage.getText().toString().trim();
80 if (!userMsg.isEmpty()) {
81 new Thread(new ThreadSendMsg(userMsg)).start();
82 }
83 }
84 });
85 }
86
87
88 private PrintWriter output;
89 private BufferedReader input;
90
91 class ThreadConnect implements Runnable {
92 @Override
93 public void run() {
94 Socket socket;
95 try {
96 socket = new Socket(SERVER_IP, SERVER_PORT);
97 soc_out_stream = socket.getOutputStream();
98 output = new PrintWriter(soc_out_stream);
99 input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
100 in_stream = socket.getInputStream();
101
102 runOnUiThread(new Runnable() {
103 @Override
104 public void run() {
105 chatMessages.setText("Connected to server\n");
106 }
107 });
108 new Thread(new ChatThread()).start();
109 } catch (IOException e) {
110 e.printStackTrace();
111 }
112 }
113 }
114
115 class ChatThread implements Runnable {
116 @Override
117 public void run() {
118 //Handshake
119 String keyBytes = "";
120 try {
121 String line = input.readLine();
122 while (!line.equals("-----END PUBLIC KEY-----")) {
123 keyBytes += line + "\n";
124 line = input.readLine();
125 }
126 } catch (IOException e) {
127 e.printStackTrace();
128 }
129
130
131 String pubKeyPEM = keyBytes.replace("-----BEGIN PUBLIC KEY-----\n", "");
132 pubKeyPEM = pubKeyPEM.replace("-----END PUBLIC KEY-----", "");
133 byte[] encoded = Base64.decode(pubKeyPEM, android.util.Base64.DEFAULT);
134 X509EncodedKeySpec spec =
135 new X509EncodedKeySpec(encoded);
136 final PublicKey pub_key;
137 try {
138 cipher_rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
139 } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
140 e.printStackTrace();
141 }
142 try {
143 KeyFactory kf = KeyFactory.getInstance("RSA");
144 pub_key = kf.generatePublic(spec);
145
146 cipher_rsa.init(Cipher.ENCRYPT_MODE, pub_key);
147 } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException e) {
148 System.err.println("");
149 }
150
151
152 byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
153 IvParameterSpec ivspec = new IvParameterSpec(iv);
154
155 try {
156 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
157
158 SecureRandom r = new SecureRandom();
159 byte[] aesKey = new byte[16];
160 r.nextBytes(aesKey);
161
162 try {
163 cipher_rsa.update(aesKey);
164 try {
165 byte[] cipherText = cipher_rsa.doFinal();
166 soc_out_stream.write(cipherText);
167 soc_out_stream.flush();
168 } catch (BadPaddingException | IllegalBlockSizeException e) {
169 e.printStackTrace();
170 }
171
172 } catch (IOException e) {
173 e.printStackTrace();
174 }
175
176 SecretKey tmp = new SecretKeySpec(aesKey, "AES");
177 cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
178 cipher_d = Cipher.getInstance("AES/ECB/PKCS5Padding");
179 cipher.init(Cipher.ENCRYPT_MODE, tmp);
180 cipher_d.init(Cipher.DECRYPT_MODE, tmp);
181
182 AlgorithmParameters params = cipher.getParameters();
183
184 } catch (NoSuchAlgorithmException | NoSuchPaddingException
185 | InvalidKeyException e) {
186 e.printStackTrace();
187 }
188
189 while (true) {
190 try {
191 final byte[] message = new byte[4096];
192 final int recv = in_stream.read(message);
193 if (message != null) {
194// cipher_d.update(Base64.decode(message, android.util.Base64.DEFAULT));
195 runOnUiThread(new Runnable() {
196 @Override
197 public void run() {
198 try {
199 byte[] cyph = new byte[recv];
200 System.arraycopy(message, 0, cyph, 0, recv);
201 byte[] plain = cipher_d.doFinal(cyph);
202 String msg = new String(plain, Charset.forName("UTF-8"));
203 chatMessages.append("Server: " + msg + "\n");
204 } catch (BadPaddingException | IllegalBlockSizeException e) {
205 e.printStackTrace();
206 }
207 }
208 });
209 } else {
210 ThreadConnect = new Thread(new ThreadConnect());
211 ThreadConnect.start();
212 return;
213 }
214 } catch (IOException e) {
215 e.printStackTrace();
216 }
217 }
218 }
219 }
220
221 class ThreadSendMsg implements Runnable {
222 private String message;
223
224 ThreadSendMsg(String message) {
225 this.message = message;
226 }
227
228 @Override
229 public void run() {
230 byte[] b = message.getBytes();
231 cipher.update(b);
232 try {
233 byte[] cipher_text = cipher.doFinal();
234 soc_out_stream.write(cipher_text);
235 soc_out_stream.flush();
236 } catch (BadPaddingException | IllegalBlockSizeException | IOException e) {
237 e.printStackTrace();
238 }
239 runOnUiThread(new Runnable() {
240 @Override
241 public void run() {
242 chatMessages.append("Сlient: " + message + "\n");
243 userMessage.setText("");
244 }
245 });
246 }
247 }
248}
249
250
251