· 9 years ago · Dec 09, 2016, 01:57 PM
1package scaltot904.univtln.fr.tp2cryptoandroid;
2
3import android.app.Activity;
4import android.content.Context;
5import android.os.Bundle;
6import android.text.Editable;
7import android.text.TextWatcher;
8import android.util.Base64;
9import android.util.Log;
10import android.view.View;
11import android.widget.ArrayAdapter;
12import android.widget.Button;
13import android.widget.EditText;
14import android.widget.Spinner;
15import android.widget.TextView;
16import android.widget.Toast;
17
18import java.io.UnsupportedEncodingException;
19import java.security.InvalidKeyException;
20import java.security.Key;
21import java.security.KeyPair;
22import java.security.KeyPairGenerator;
23import java.security.NoSuchAlgorithmException;
24import java.security.SecureRandom;
25import java.util.ArrayList;
26import java.util.List;
27
28import javax.crypto.Cipher;
29import javax.crypto.KeyGenerator;
30import javax.crypto.Mac;
31import javax.crypto.SecretKey;
32import javax.crypto.spec.SecretKeySpec;
33
34import static android.content.ContentValues.TAG;
35
36public class MainActivity extends Activity {
37
38 private Spinner spinnerAllEncryptionModes;
39 private EditText editTextMessageToEncrypt;
40 private Button validateButton;
41 private TextView textEncoded;
42 private TextView textDecoded;
43 private Context context;
44 /**
45 * shared settings for all encryption types
46 */
47 private KeyGenerator keyGen;
48 private Key key;
49 private Cipher c;
50 /**
51 * MAC mode
52 */
53 private static final String MAC1 = "HmacSHA256";
54 private static final String MAC2 = "HmacMD5";
55 private Mac mac;
56 private String cle;
57 private String macResult;
58 private SecretKey secretKeyMac;
59
60 /**
61 * settings for AES mode
62 */
63 private static final String AES = "AES";
64 private SecretKeySpec sks;
65 private byte[] encodedBytes = null;
66 private byte[] decodedBytes = null;
67
68 /**
69 * settings for TripleDES (DESede) mode
70 * DESbis used to show that cipher set "ECB" mode and "PKCS5Padding" padding to default. So DES and DESbis produces the same code.
71 */
72 private static final String DESede = "DESede";
73 private SecretKey secretKeyDesede;
74
75 /**
76 * settings for DES mode
77 */
78 private static final String DES = "DES";
79 private static final String DESbis = "DES/ECB/PKCS5Padding";
80 private SecretKey secretKeyDes;
81
82 /**
83 * settings for RSA mode
84 */
85 private static final String RSA = "RSA";
86 private Key publicKey = null;
87 private Key privateKey = null;
88
89
90
91 @Override
92 public void onCreate(Bundle savedInstanceState) {
93 super.onCreate(savedInstanceState);
94 setContentView(R.layout.activity_main);
95 textEncoded = (TextView)findViewById(R.id.tvencoded);
96 textDecoded = (TextView)findViewById(R.id.tvdecoded);
97 context = this.getBaseContext();
98 spinnerAllEncryptionModes = (Spinner) findViewById(R.id.spinner);
99 editTextMessageToEncrypt = (EditText) findViewById(R.id.editText2);
100 validateButton = (Button) findViewById(R.id.imagebutton);
101
102 List cryptoTypes = new ArrayList();
103 cryptoTypes.add(AES);
104 cryptoTypes.add(RSA);
105 cryptoTypes.add(DES);
106 cryptoTypes.add(DESede);
107 cryptoTypes.add(DESbis);
108 cryptoTypes.add(MAC1);
109 cryptoTypes.add(MAC2);
110
111 TextWatcher watcher= new TextWatcher() {
112 public void afterTextChanged(Editable editable) {
113 if (editTextMessageToEncrypt.getText().toString().equals("") | editTextMessageToEncrypt.getText().toString().equals(null)){
114 validateButton.setClickable(false);
115 Toast.makeText(context, "Le message est vide.. -_-' ", Toast.LENGTH_LONG).show();
116 }
117
118 else {
119 validateButton.setClickable(true);
120 }
121 }
122
123 public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
124 public void onTextChanged(CharSequence s, int start, int before, int count) {}
125 };
126 editTextMessageToEncrypt.addTextChangedListener(watcher);
127
128 ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item,cryptoTypes);
129 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
130 spinnerAllEncryptionModes.setAdapter(adapter);
131
132 }
133
134
135 /**
136 * Crypto function wich is generates as well encoded and decoded text as MAC code. Depends on cryptoMode
137 * @param cryptoMode
138 * @throws UnsupportedEncodingException
139 * @throws NoSuchAlgorithmException
140 * @throws InvalidKeyException
141 */
142 public void Crypto(String cryptoMode) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
143
144 textDecoded.setText("");
145 if (cryptoMode == MAC1 | cryptoMode == MAC2)
146 calculerMAC(cryptoMode);
147 else {
148 Encode(cryptoMode);
149 Decode(cryptoMode);
150 }
151 }
152
153 /**
154 * launch Crypto function with spinnerAllEncryptionModes selected item
155 * @param view
156 * @throws UnsupportedEncodingException
157 * @throws NoSuchAlgorithmException
158 * @throws InvalidKeyException
159 */
160 public void validateButton(View view) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
161 Crypto(spinnerAllEncryptionModes.getSelectedItem().toString());
162 }
163
164 /**
165 * init key for RSA mode
166 */
167 public void RSA_keyInit(){
168
169 try {
170 KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
171 kpg.initialize(1024);
172 KeyPair kp = kpg.genKeyPair();
173 publicKey = kp.getPublic();
174 privateKey = kp.getPrivate();
175 } catch (Exception e) {
176 Log.e(TAG, "RSA key pair error");
177 }
178 }
179
180
181 /**
182 * init key for AES mode
183 */
184 public void AES_keyInit(){
185
186 try {
187 SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
188 sr.setSeed("any data used as random seed".getBytes());
189 KeyGenerator kg = KeyGenerator.getInstance(AES);
190 kg.init(128, sr);
191 sks = new SecretKeySpec((kg.generateKey()).getEncoded(), AES);
192 } catch (Exception e) {
193 Log.e(AES, "AES secret key spec error");
194 }
195 }
196
197 /**
198 * init key for TripleDES (DESede) mode
199 */
200 public void DESede_keyInit(){
201
202 try {
203 keyGen = KeyGenerator.getInstance(DESede);
204 keyGen.init(168);
205 secretKeyDesede = keyGen.generateKey();
206 } catch (Exception e) {
207 Log.e(DESede, "DESede secret key spec error");
208 }
209 }
210
211 /**
212 * init key for DES mode
213 */
214 public void DES_keyInit(){
215
216 try {
217 keyGen = KeyGenerator.getInstance(DES);
218 secretKeyDes = keyGen.generateKey();
219 } catch (Exception e) {
220 Log.e(DESede, "DESede secret key spec error");
221 }
222 }
223
224 /**
225 * encode any message with any encryption types
226 * @param cryptoMode
227 */
228 public void Encode(String cryptoMode){
229 /* comment if you want keep the same key for each round of one encryption mode*/
230 keyInitFunction(cryptoMode);
231 key = getKeyFfunction(cryptoMode);
232 if (cryptoMode == RSA)
233 key = privateKey;
234 try {
235 c = Cipher.getInstance(cryptoMode);
236 c.init(Cipher.ENCRYPT_MODE, key);
237 encodedBytes = c.doFinal(editTextMessageToEncrypt.getText().toString().getBytes());
238 } catch (Exception e) {
239 Log.e(TAG, cryptoMode + " encryption error");
240 }
241 textEncoded.setText(Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
242 }
243
244
245 /**
246 * decode any encryption types and set encoded text
247 * @param cryptoMode
248 */
249 public void Decode(String cryptoMode){
250 try {
251 c.init(Cipher.DECRYPT_MODE, getKeyFfunction(cryptoMode));
252 decodedBytes = c.doFinal(encodedBytes);
253 } catch (Exception e) {
254 Log.e(TAG, cryptoMode + " decryption error");
255 }
256 textDecoded.setText(new String(decodedBytes) + "\n");
257 }
258
259
260 /**
261 * return the key corresponding to the encryption types define by cryptoMode
262 * @param cryptoMode
263 * @return key
264 */
265 public Key getKeyFfunction(String cryptoMode){
266 if (cryptoMode == RSA) {
267 key = publicKey;
268 }
269 else if (cryptoMode == AES) {
270 key = sks;
271 }
272 else if (cryptoMode == DES | cryptoMode == DESbis){
273 key = secretKeyDes;
274 }
275 else if (cryptoMode == DESede)
276 key = secretKeyDesede;
277
278 return key;
279 }
280
281
282 /**
283 * comment if you want use the same key for each encryption
284 * @param cryptoMode
285 */
286 public void keyInitFunction(String cryptoMode){
287 if (cryptoMode == RSA){
288 RSA_keyInit();
289 }
290 else if (cryptoMode == AES) {
291 AES_keyInit();
292 }
293 else if (cryptoMode == DESede){
294 DESede_keyInit();
295 }
296 else if (cryptoMode == DES | cryptoMode == DESbis)
297 DES_keyInit();
298 }
299
300
301 /**
302 * generates Mac code for authentification
303 * @param macMode
304 * @throws UnsupportedEncodingException
305 * @throws NoSuchAlgorithmException
306 * @throws InvalidKeyException
307 */
308 public void calculerMAC(String macMode) throws UnsupportedEncodingException, NoSuchAlgorithmException,InvalidKeyException {
309 cle = editTextMessageToEncrypt.getText().toString();
310 secretKeyMac = new SecretKeySpec(cle.getBytes("UTF-8"), macMode);
311 textEncoded.setText("cle : " + bytesToHex(secretKeyMac.getEncoded()));
312 mac = Mac.getInstance(secretKeyMac.getAlgorithm());
313 mac.init(secretKeyMac);
314 encodedBytes = editTextMessageToEncrypt.getText().toString().getBytes("UTF-8");
315 decodedBytes = mac.doFinal(encodedBytes);
316 macResult = bytesToHex(decodedBytes);
317 textDecoded.setText(macResult);
318 }
319
320
321 /**
322 * converts bytes in Hexa to display it clearly
323 * @param b
324 * @return
325 */
326 public String bytesToHex(byte[] b) {
327 char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
328 StringBuffer buf = new StringBuffer();
329 for (int j = 0; j < b.length; j++) {
330 buf.append(hexDigit[(b[j] >> 4) & 0x0f]);
331 buf.append(hexDigit[b[j] & 0x0f]);
332 }
333 return buf.toString();
334 }
335}