· 5 years ago · Jun 30, 2020, 01:12 AM
1package com.bruh.chatapp;
2
3
4import android.util.Log;
5
6import java.io.UnsupportedEncodingException;
7import java.lang.reflect.Array;
8import java.nio.charset.StandardCharsets;
9import java.security.NoSuchAlgorithmException;
10import java.util.Arrays;
11
12import javax.crypto.KeyGenerator;
13import javax.crypto.SecretKey;
14
15public class aesContoh{
16
17 static char[] input; //Penampung input
18 static int[][] output; //Penampung output
19 static char[] secret; //Penampung secret key
20 static int[][] state; //Penampung status
21 static int[][] rahasia; //Penampung konversi secret key ke int
22 static int[][] s_box; //Penampung sbox
23 static int[][] invs_box; //Penampung inverse s-box
24 static int nb, nr,nk; //Penampung nb dan nr
25 static byte[][] Kunci;
26 //Isi S-Box
27 public static int[] sbox = {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
28 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
29 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
30 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
31 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
32 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
33 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
34 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
35 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
36 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
37 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
38 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
39 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
40 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
41 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
42 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
43
44//Isi Inverse S-Box
45public static int[] invsbox = {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
46 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
47 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
480x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
490x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
500x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
510x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
52 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
53 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
54 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
55 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
56 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
57 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
58 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
59 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
600x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
61
62
63//Isi RCon untuk Key Expansion
64 public static final int[] rcon = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
65 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
66 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
67 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
68 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
69 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
70 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
71 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
72 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
73 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
74 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
75 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
76 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
77 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
78 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
79 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb};
80
81/*Prosedur enkripsi*/
82 public static byte[] EncryptBlock(byte[] in, byte[][] password){
83
84
85 byte[] out = new byte[in.length];
86 //inisiasi state
87 byte[][] state = new byte[4][nb];
88
89 for (int i = 0; i<4;i++ ) {
90 for(int j=0;j<nb;j++){
91 state[i][j] = in[i+j*4];
92 }
93 }
94
95 System.out.printf("Sesudah:\n");
96 state = AddRoundKey(state,password,0); //Proses AddRoundKey pertama
97
98 //Looping Standard Round
99 int round; //nr-1
100 for(round=1;round<nr;round++){
101 state = ByteSub(state);
102 state = ShiftRow(state);
103 state = MixColumn(state);
104 state = AddRoundKey(state,password,round);
105 }
106
107 // //Proses final round
108 state = ByteSub(state);
109 state = ShiftRow(state);
110 state = AddRoundKey(state,password,nr);
111
112
113 //Memasukkan isi state ke dalam output
114 for(int i=0;i<in.length;i++){
115 out[i%4*4+i/4] = state[i/4][i%4];
116 }
117
118 return out;
119 }
120
121
122 //Proses AddRoundKey
123 private static byte[][] AddRoundKey(byte[][] state, byte[][] secret, int round){
124
125 byte[][] temp = new byte[state.length][state[0].length];
126
127 for(int j=0;j<nb;j++){
128 for(int i=0;i<state[j].length;i++){
129 temp[j][i] = (byte) (state[j][i] ^ secret[round*nb+j][j]);
130 }
131 }
132
133 return temp;
134 }
135
136
137 //Proses SubByte
138 private static byte[][] ByteSub(byte[][] state){
139 // System.out.println(state.length);
140 // System.out.println(state[0].length);
141
142 byte[][] temp = new byte[state.length][state[0].length];
143
144 for(int i=0;i<4;i++){
145 for(int j=0;j<nb;j++){
146 int plot = state[i][j];
147 temp[i][j] = (byte) (sbox[plot & 0x000000ff] & 0xff);
148 }
149 }
150
151 return temp;
152
153 }
154
155 //Proses MixColumn
156 private static byte[][] MixColumn(byte[][] state){
157 int[] MixColumnMatrix = new int[4];
158 byte b2 = (byte) 0x02, b3 = (byte)0x03;
159 for(int j = 0;j<4;j++){
160 MixColumnMatrix[0] = Gmul(b2,state[0][j]) ^ Gmul(b3,state[1][j]) ^ state[2][j] ^ state[3][j];
161 MixColumnMatrix[1] = state[0][j] ^ Gmul(b2, state[1][j]) ^ Gmul(b3, state[2][j]) ^ state[3][j];
162 MixColumnMatrix[2] = state[0][j] ^ state[1][j] ^ Gmul(b2,state[2][j]) ^ Gmul(b3,state[3][j]);
163 MixColumnMatrix[3] = Gmul(b3,state[0][j]) ^ state[1][j] ^ state[2][j] ^ Gmul(b2, state[3][j]);
164
165 for(int i=0;i<4;i++){
166 state[i][j] = (byte)(MixColumnMatrix[i]);
167 }
168
169 }
170
171 return state;
172
173 }
174
175 //Proses perkalian matriks
176 public static byte Gmul(byte a, byte b) {
177 byte aa = a, bb = b, r=0, t;
178 while(aa !=00){
179 if((aa&1) != 0){
180 r = (byte)(r^bb);
181 }
182 t = (byte)(bb & 0x80);
183 bb = (byte) (bb << 1);
184 if(t != 0 ){
185 bb = (byte)(bb ^ 0x1b);
186 }
187 aa = (byte)((aa & 0xff) >> 1);
188 }
189
190 return r;
191 }
192
193
194
195 //Proses ShiftRow
196 private static byte[][] ShiftRow(byte[][] state){
197
198 byte[] t = new byte[4];
199 for(int i=0;i<4;i++){
200 for(int j=0;j<nb;j++){
201 t[j] = state[i][(j+i)%nb];
202 }
203 for(int j=0;j<nb;j++){
204 state[i][j] = t[j];
205 }
206 }
207 return state;
208 }
209
210
211 /*Proses Ekspansi Kunci*/
212 private static byte[][] KeyExpansion(byte secret[]){
213 byte[][] w = new byte[nb*(nr+1)][4];
214 //byte[] temp = new byte[4];
215 int i=0;
216 while(i<nk){
217 w[i][0] = secret[i*4];
218 w[i][1] = secret[i*4+1];
219 w[i][2] = secret[i*4+2];
220 w[i][3] = secret[i*4+3];
221
222 i++;
223 }
224
225 i = nk;
226 while(i<nb*(nr+1)){
227 //temp = w[i-1];V0HwV
228 byte[] temp = new byte[4];
229 for(int k=0;k<4;k++){
230 temp[k] = w[i-1][k];
231 }
232 if(i%nk==0){
233 temp = SubWord(RotWord(temp));
234 temp[0] = (byte) (temp[0] ^ rcon[i/nk] &0xff);
235 }else if((nk > 6) && (i%nk==4)){
236 temp = SubWord(temp);
237 }
238 w[i] = xor_func(w[i-nk],temp);
239 i++;
240 }
241 return w;
242
243 }
244
245
246 public static byte[] SubWord(byte[] w){
247 byte[] aftersub = new byte[w.length];
248 for(int i=0;i<aftersub.length;i++){
249 aftersub[i] = (byte) (sbox[w[i] & 0x000000ff] & 0xff);
250 }
251
252 return aftersub;
253 }
254
255 public static byte[] RotWord(byte[] w){
256 byte[] afterRot = new byte[w.length];
257 for(int i=0;i<3;i++){
258 afterRot[i] = w[i+1];
259 }
260 afterRot[3] = w[0];
261 return afterRot;
262 }
263
264
265
266
267 public static byte[] DecryptBlocks(byte[] in, byte[][] password){
268 byte[] out = new byte[in.length];
269 byte[][] state = new byte[4][nb];
270 for (int i = 0; i<4;i++ ) {
271 state[i/4][i%4] = in[i%4*4+i/4];
272 }
273
274 state = AddRoundKey(state,password,nr);
275 int round;
276 for(round = nr-1;round >= 1;round--){
277 state = InvShiftRows(state);
278 state = InvSubBytes(state);
279 state = AddRoundKey(state,password,round);
280 state = InvMixColumns(state);
281 }
282 state = InvShiftRows(state);
283 state = InvSubBytes(state);
284 state = AddRoundKey(state,password,0);
285
286
287 for(int i=0;i<in.length;i++){
288 out[i%4*4+i/4] = state[i/4][i%4];
289 }
290
291 return out;
292 }
293
294
295 private static byte[] xor_func(byte[] a, byte[] b) {
296 byte[] out = new byte[a.length];
297 for (int i = 0; i < a.length; i++) {
298 out[i] = (byte) (a[i] ^ b[i]);
299 }
300 return out;
301
302 }
303
304 private static byte[][] InvShiftRows(byte[][] state){
305 byte[] t = new byte[4];
306
307 for(int i=0;i<4;i++){
308 for(int j=0;j<nb;j++){
309 t[(j+i)%nb] = state[i][j];
310 }
311 for(int j=0;j<nb;j++){
312 state[i][j] = t[j];
313 }
314 }
315 return state;
316 }
317
318 private static byte[][] InvSubBytes(byte[][] state){
319 // System.out.println(state.length);
320 // System.out.println(state[0].length);
321
322 for(int i=0;i<4;i++){
323 for(int j=0;j<nb;j++){
324 byte plot = state[i][j];
325 state[i][j] = (byte) (invsbox[plot & 0x000000ff] & 0xff);;
326 }
327 }
328
329 return state;
330
331 }
332
333 private static byte[][] InvMixColumns(byte[][] state){
334 int[] InvMixColumns = new int[4];
335 byte be = (byte) 0x0e, bb = (byte)0x0b, bd = (byte)0x0d,b9 = (byte)0x09;
336 for(int j =0;j<4;j++ ){
337 InvMixColumns[0] = Gmul(be,state[0][j]) ^ Gmul(bb,state[1][j]) ^ Gmul(bd,state[2][j]) ^ Gmul(b9,state[3][j]);
338 InvMixColumns[1] = Gmul(b9,state[0][j]) ^ Gmul(be,state[1][j]) ^ Gmul(bb,state[2][j]) ^ Gmul(bd,state[3][j]);
339 InvMixColumns[2] = Gmul(bd,state[0][j]) ^ Gmul(b9,state[1][j]) ^ Gmul(be,state[2][j]) ^ Gmul(bb,state[3][j]);
340 InvMixColumns[3] = Gmul(bb,state[0][j]) ^ Gmul(bd,state[1][j]) ^ Gmul(b9,state[2][j]) ^ Gmul(be,state[3][j]);
341
342 for(int i=0;i<4;i++){
343 state[i][j] = (byte)(InvMixColumns[i]);
344 }
345 }
346 return state;
347 }
348
349 public static byte[] Encrypt(byte[] in, byte[] secret){
350 nb = 4;
351 nk = secret.length/4;
352 nr = nk+6;
353 int length = 0;
354 byte[] padding = new byte[1];
355 int i;
356 length = 16 - in.length % 16;
357
358
359 padding = new byte[length];
360 padding[0] = (byte) 0x80;
361 for(i=1 ; i < length;i++){
362 padding[i] = 0;
363 }
364
365 byte[] temp = new byte[in.length +length];
366 byte[] blocks = new byte[16];
367
368 Kunci = KeyExpansion(secret);
369 int hitung = 0;
370 for(i=0;i<in.length + length; i++){
371 if(i>0 && i%16 == 0){
372 blocks = EncryptBlock(blocks,Kunci);
373 System.arraycopy(blocks,0,temp,i-16,blocks.length);
374 }
375 if(i < in.length){
376 blocks[i%16] = in[i];
377 }else{
378 blocks[i%16] = padding[hitung%16];
379 hitung++;
380 }
381 }
382 if(blocks.length == 16){
383 blocks = EncryptBlock(blocks,Kunci);
384 System.arraycopy(blocks,0,temp,i-16,blocks.length);
385 }
386
387 return temp;
388 }
389
390 public static byte[] Decrypt(byte[] in, byte[] secret){ //Prosedur dekripsi encrypted text
391 int i;
392 byte[] temp = new byte[in.length];
393 byte[] blocks = new byte[16];
394 nb = 4;
395 nk = secret.length/4;
396 nr = nk+6;
397 Kunci = KeyExpansion(secret); //Mengambil Kunci sesi dari Key Expansion
398
399 for(i=0;i<in.length;i++){
400 if(i > 0 && i %16==0){
401 blocks = DecryptBlocks(blocks,Kunci); //Dekripsi text per blok dengan kunci sesi
402 System.arraycopy(blocks,0,temp,i-16,blocks.length); //Isi temp dengan blok terdeskripsi
403 }
404 if(i < in.length){
405 blocks[i%16] = in[i];
406 }
407
408 }
409 blocks = DecryptBlocks(blocks,Kunci); //Melakukan dekripsi text untuk blok terakhir
410 //Log.d("temp length:", String.valueOf(temp.length));
411 System.arraycopy(blocks,0,temp,i-16,blocks.length);
412 Log.d("temp isi: ", Arrays.toString(temp));
413 temp = DeletePadding(temp);
414 return temp;
415 }
416
417 public static byte[] KeyGen(){
418 String secret = new String();
419 byte[] sec = new byte[secret.length()];
420 try{
421 KeyGenerator keygen = KeyGenerator.getInstance("AES");
422 keygen.init(128);
423 SecretKey secretKey = keygen.generateKey();
424 sec = secretKey.getEncoded();
425 }catch (NoSuchAlgorithmException e){
426 e.printStackTrace();
427 }
428 return sec;
429 }
430
431 public static byte[] DeletePadding(byte[] in){
432 int count = 0;
433 int i = in.length - 1;
434 while(in[i] == 0){
435 count++;
436 i--;
437 }
438
439 byte[] temp = new byte[in.length-count-1];
440 System.arraycopy(in,0,temp,0,temp.length);
441 return temp;
442 }
443}