· 6 years ago · Apr 20, 2019, 04:42 PM
1package Encrypt;
2
3import java.nio.file.Files;
4import java.nio.file.Paths;
5import java.io.FileWriter;
6import java.io.InputStream;
7import java.io.OutputStream;
8import java.io.FileInputStream;
9import java.io.FileOutputStream;
10import java.util.Base64;
11import java.util.Arrays;
12import java.security.Key;
13import java.security.KeyPair;
14import java.security.KeyPairGenerator;
15import java.security.KeyFactory;
16import java.security.PrivateKey;
17import java.security.PublicKey;
18import java.security.SecureRandom;
19import java.security.spec.PKCS8EncodedKeySpec;
20import java.security.spec.X509EncodedKeySpec;
21import javax.crypto.Cipher;
22import javax.crypto.KeyGenerator;
23import javax.crypto.SecretKey;
24import javax.crypto.spec.SecretKeySpec;
25import javax.crypto.spec.IvParameterSpec;
26
27
28
29public class AES
30
31{
32
33 static private Base64.Encoder encoder = Base64.getEncoder();
34
35 static SecureRandom srandom = new SecureRandom();
36
37
38
39 static private void processFile(Cipher ci,InputStream in,OutputStream out)
40
41 throws javax.crypto.IllegalBlockSizeException,
42
43 javax.crypto.BadPaddingException,
44
45 java.io.IOException
46
47 {
48
49 byte[] ibuf = new byte[1024];
50
51 int len;
52
53 while ((len = in.read(ibuf)) != -1) {
54
55 byte[] obuf = ci.update(ibuf, 0, len);
56
57 if ( obuf != null ) out.write(obuf);
58
59 }
60
61 byte[] obuf = ci.doFinal();
62
63 if ( obuf != null ) out.write(obuf);
64
65 }
66
67
68
69 static private void processFile(Cipher ci,String inFile,String outFile)
70
71 throws javax.crypto.IllegalBlockSizeException,
72
73 javax.crypto.BadPaddingException,
74
75 java.io.IOException
76
77 {
78
79 try (FileInputStream in = new FileInputStream(inFile);
80
81 FileOutputStream out = new FileOutputStream(outFile)) {
82
83 processFile(ci, in, out);
84
85 }
86
87 }
88
89
90
91 static private void doGenkey(String[] args)
92
93 throws java.security.NoSuchAlgorithmException,
94
95 java.io.IOException
96
97 {
98
99 if ( args.length == 0 ) {
100
101 System.err.println("genkey -- need fileBase");
102
103 return;
104
105 }
106
107
108
109 int index = 0;
110
111 String fileBase = args[index++];
112
113 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
114
115 kpg.initialize(2048);
116
117 KeyPair kp = kpg.generateKeyPair();
118
119 try (FileOutputStream out = new FileOutputStream(fileBase + ".key")) {
120
121 out.write(kp.getPrivate().getEncoded());
122
123 }
124
125
126
127 try (FileOutputStream out = new FileOutputStream(fileBase + ".pub")) {
128
129 out.write(kp.getPublic().getEncoded());
130
131 }
132
133 }
134
135
136
137 /* Larger data gives:
138
139 *
140
141 * javax.crypto.IllegalBlockSizeException: Data must not be longer
142
143 * than 245 bytes
144
145 */
146
147 static private void doEncrypt(String[] args)
148
149 throws java.security.NoSuchAlgorithmException,
150
151 java.security.spec.InvalidKeySpecException,
152
153 javax.crypto.NoSuchPaddingException,
154
155 javax.crypto.BadPaddingException,
156
157 java.security.InvalidKeyException,
158
159 javax.crypto.IllegalBlockSizeException,
160
161 java.io.IOException
162
163 {
164
165 if ( args.length != 2 ) {
166
167 System.err.println("enc pvtKeyFile inputFile");
168
169 System.exit(1);
170
171 }
172
173
174
175 int index = 0;
176
177 String pvtKeyFile = args[index++];
178
179 String inputFile = args[index++];
180
181 byte[] bytes = Files.readAllBytes(Paths.get(pvtKeyFile));
182
183 PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
184
185 KeyFactory kf = KeyFactory.getInstance("RSA");
186
187 PrivateKey pvt = kf.generatePrivate(ks);
188
189
190
191 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
192
193 cipher.init(Cipher.ENCRYPT_MODE, pvt);
194
195 processFile(cipher, inputFile, inputFile + ".enc");
196
197 }
198
199
200
201 static private void doDecrypt(String[] args)
202
203 throws java.security.NoSuchAlgorithmException,
204
205 java.security.spec.InvalidKeySpecException,
206
207 javax.crypto.NoSuchPaddingException,
208
209 javax.crypto.BadPaddingException,
210
211 java.security.InvalidKeyException,
212
213 javax.crypto.IllegalBlockSizeException,
214
215 java.io.IOException
216
217 {
218
219 if ( args.length != 2 ) {
220
221 System.err.println("dec pubKeyFile inputFile");
222
223 System.exit(1);
224
225 }
226
227
228
229 int index = 0;
230
231 String pubKeyFile = args[index++];
232
233 String inputFile = args[index++];
234
235 byte[] bytes = Files.readAllBytes(Paths.get(pubKeyFile));
236
237 X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
238
239 KeyFactory kf = KeyFactory.getInstance("RSA");
240
241 PublicKey pub = kf.generatePublic(ks);
242
243
244
245 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
246
247 cipher.init(Cipher.DECRYPT_MODE, pub);
248
249 processFile(cipher, inputFile, inputFile + ".ver");
250
251 }
252
253
254
255 static private void doEncryptRSAWithAES(String[] args)
256
257 throws java.security.NoSuchAlgorithmException,
258
259 java.security.InvalidAlgorithmParameterException,
260
261 java.security.InvalidKeyException,
262
263 java.security.spec.InvalidKeySpecException,
264
265 javax.crypto.NoSuchPaddingException,
266
267 javax.crypto.BadPaddingException,
268
269 javax.crypto.IllegalBlockSizeException,
270
271 java.io.IOException
272
273 {
274
275 if ( args.length != 2 ) {
276
277 System.err.println("enc pvtKeyFile inputFile");
278
279 System.exit(1);
280
281 }
282
283
284
285 int index = 0;
286
287 String pvtKeyFile = args[index++];
288
289 String inputFile = args[index++];
290
291 byte[] bytes = Files.readAllBytes(Paths.get(pvtKeyFile));
292
293 PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
294
295 KeyFactory kf = KeyFactory.getInstance("RSA");
296
297 PrivateKey pvt = kf.generatePrivate(ks);
298
299
300
301 KeyGenerator kgen = KeyGenerator.getInstance("AES");
302
303 kgen.init(128);
304
305 SecretKey skey = kgen.generateKey();
306
307
308
309 byte[] iv = new byte[128/8];
310
311 srandom.nextBytes(iv);
312
313 IvParameterSpec ivspec = new IvParameterSpec(iv);
314
315
316
317 try (FileOutputStream out = new FileOutputStream(inputFile + ".enc")) {
318
319 {
320
321 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
322
323 cipher.init(Cipher.ENCRYPT_MODE, pvt);
324
325 byte[] b = cipher.doFinal(skey.getEncoded());
326
327 out.write(b);
328
329 System.err.println("AES Key Length: " + b.length);
330
331 }
332
333
334
335 out.write(iv);
336
337 System.err.println("IV Length: " + iv.length);
338
339
340
341 Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
342
343 ci.init(Cipher.ENCRYPT_MODE, skey, ivspec);
344
345 try (FileInputStream in = new FileInputStream(inputFile)) {
346
347 processFile(ci, in, out);
348
349 }
350
351 }
352
353 }
354
355
356
357 static private void doDecryptRSAWithAES(String[] args)
358
359 throws java.security.NoSuchAlgorithmException,
360
361 java.security.InvalidAlgorithmParameterException,
362
363 java.security.InvalidKeyException,
364
365 java.security.spec.InvalidKeySpecException,
366
367 javax.crypto.NoSuchPaddingException,
368
369 javax.crypto.BadPaddingException,
370
371 javax.crypto.IllegalBlockSizeException,
372
373 java.io.IOException
374
375 {
376
377 if ( args.length != 2 ) {
378
379 System.err.println("enc pvtKeyFile inputFile");
380
381 System.exit(1);
382
383 }
384
385
386
387 int index = 0;
388
389 String pubKeyFile = args[index++];
390
391 String inputFile = args[index++];
392
393 byte[] bytes = Files.readAllBytes(Paths.get(pubKeyFile));
394
395 X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
396
397 KeyFactory kf = KeyFactory.getInstance("RSA");
398
399 PublicKey pub = kf.generatePublic(ks);
400
401
402
403 try (FileInputStream in = new FileInputStream(inputFile)) {
404
405 SecretKeySpec skey = null;
406
407 {
408
409 Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
410
411 cipher.init(Cipher.DECRYPT_MODE, pub);
412
413 byte[] b = new byte[256];
414
415 in.read(b);
416
417 byte[] keyb = cipher.doFinal(b);
418
419 skey = new SecretKeySpec(keyb, "AES");
420
421 }
422
423
424
425 byte[] iv = new byte[128/8];
426
427 in.read(iv);
428
429 IvParameterSpec ivspec = new IvParameterSpec(iv);
430
431
432
433 Cipher ci = Cipher.getInstance("AES/CBC/PKCS5Padding");
434
435 ci.init(Cipher.DECRYPT_MODE, skey, ivspec);
436
437
438
439 try (FileOutputStream out = new FileOutputStream(inputFile+".ver")){
440
441 processFile(ci, in, out);
442
443 }
444
445 }
446
447 }
448
449
450
451 static public void main(String[] args) throws Exception
452
453 {
454
455 if ( args.length == 0 ) {
456
457 System.err.print("usage: java sample1 command params..\n" +
458
459 "where commands are:\n" +
460
461 " genkey fileBase\n" +
462
463 " tnyenc pvtKeyFile inputFile\n" +
464
465 " tnydec pubKeyFile inputFile\n" +
466
467 " enc pvtKeyFile inputFile\n" +
468
469 " dec pubKeyFile inputFile\n");
470
471 System.exit(1);
472
473 }
474
475
476
477 int index = 0;
478
479 String command = args[index++];
480
481 String[] params = Arrays.copyOfRange(args, index, args.length);
482
483 if ( command.equals("genkey") ) doGenkey(params);
484
485 else if ( command.equals("tnyenc") ) doEncrypt(params);
486
487 else if ( command.equals("tnydec") ) doDecrypt(params);
488
489 else if ( command.equals("enc") ) doEncryptRSAWithAES(params);
490
491 else if ( command.equals("dec") ) doDecryptRSAWithAES(params);
492
493 else throw new Exception("Unknown command: " + command);
494
495 }
496
497}