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