1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.crypto;
21
22 import org.waarp.common.digest.FilesystemBasedDigest;
23 import org.waarp.common.exception.CryptoException;
24 import org.waarp.common.file.FileUtils;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27 import org.waarp.common.utility.WaarpStringUtils;
28
29 import javax.crypto.Cipher;
30 import javax.crypto.KeyGenerator;
31 import javax.crypto.spec.SecretKeySpec;
32 import java.io.DataInputStream;
33 import java.io.File;
34 import java.io.FileInputStream;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.security.Key;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public abstract class KeyObject {
62
63
64
65 private static final WaarpLogger logger =
66 WaarpLoggerFactory.getLogger(KeyObject.class);
67
68
69
70
71 Key secretKey;
72
73
74
75
76 protected KeyObject() {
77 }
78
79
80
81
82 public abstract String getAlgorithm();
83
84
85
86
87 public abstract String getInstance();
88
89
90
91
92 public abstract int getKeySize();
93
94
95
96
97 public abstract String getFileExtension();
98
99
100
101
102 public final Key getSecretKey() {
103 return secretKey;
104 }
105
106
107
108
109 public final boolean keyReady() {
110 return secretKey != null;
111 }
112
113
114
115
116
117
118
119
120 public final byte[] getSecretKeyInBytes() {
121 if (keyReady()) {
122 return secretKey.getEncoded();
123 } else {
124 return null;
125 }
126 }
127
128
129
130
131
132
133 public final void setSecretKey(final Key secretKey) {
134 this.secretKey = secretKey;
135 }
136
137
138
139
140 public final void setSecretKey(final byte[] keyData) {
141 secretKey = new SecretKeySpec(keyData, getAlgorithm());
142 }
143
144
145
146
147
148
149
150
151
152 public final void setSecretKey(final File file)
153 throws CryptoException, IOException {
154 if (file.canRead()) {
155 final int len = (int) file.length();
156 final byte[] key = new byte[len];
157 final FileInputStream inputStream;
158 inputStream = new FileInputStream(file);
159 final DataInputStream dis = new DataInputStream(inputStream);
160 try {
161 dis.readFully(key);
162 } finally {
163 FileUtils.close(dis);
164 }
165 setSecretKey(key);
166 } else {
167 throw new CryptoException("Cannot read crypto file: " + file);
168 }
169 }
170
171
172
173
174
175
176
177
178
179 public final void saveSecretKey(final File file)
180 throws CryptoException, IOException {
181 if (keyReady() && (!file.exists() || file.canWrite())) {
182 final byte[] key = getSecretKeyInBytes();
183 final FileOutputStream outputStream = new FileOutputStream(file);
184 try {
185 outputStream.write(key);
186 outputStream.flush();
187 } finally {
188 FileUtils.close(outputStream);
189 }
190 } else {
191 throw new CryptoException("Cannot read crypto file");
192 }
193 }
194
195
196
197
198
199
200 public final void generateKey() throws Exception {
201 try {
202 final KeyGenerator keyGen = KeyGenerator.getInstance(getAlgorithm());
203 keyGen.init(getKeySize());
204 secretKey = keyGen.generateKey();
205 } catch (final Exception e) {
206 logger.warn("GenerateKey Error", e);
207 throw e;
208 }
209 }
210
211
212
213
214
215
216
217 public Cipher toCrypt() {
218 final Cipher cipher;
219 try {
220 cipher = Cipher.getInstance(getInstance());
221 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
222 } catch (final Exception e) {
223 logger.warn("Crypt Error", e);
224 return null;
225 }
226 return cipher;
227 }
228
229
230
231
232
233
234
235
236
237
238 public byte[] crypt(final byte[] plaintext) throws Exception {
239 if (!keyReady()) {
240 throw new CryptoException("Key not Ready");
241 }
242 try {
243 final Cipher cipher = Cipher.getInstance(getInstance());
244 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
245 return cipher.doFinal(plaintext);
246 } catch (final Exception e) {
247 logger.warn("Crypt Error", e);
248 throw e;
249 }
250 }
251
252
253
254
255
256
257
258
259
260
261 public final String cryptToHex(final byte[] plaintext) throws Exception {
262 final byte[] result = crypt(plaintext);
263 return encodeHex(result);
264 }
265
266
267
268
269
270
271
272
273
274
275 public final byte[] crypt(final String plaintext) throws Exception {
276 return crypt(plaintext.getBytes(WaarpStringUtils.UTF8));
277 }
278
279
280
281
282
283
284
285
286
287
288 public final String cryptToHex(final String plaintext) throws Exception {
289 return cryptToHex(plaintext.getBytes(WaarpStringUtils.UTF8));
290 }
291
292
293
294
295
296
297
298 public Cipher toDecrypt() {
299 final Cipher cipher;
300 try {
301 cipher = Cipher.getInstance(getAlgorithm());
302 cipher.init(Cipher.DECRYPT_MODE, secretKey);
303 } catch (final Exception e) {
304 logger.warn("Uncrypt Error", e);
305 return null;
306 }
307 return cipher;
308 }
309
310
311
312
313
314
315
316
317
318
319 public byte[] decrypt(final byte[] ciphertext) throws Exception {
320 if (!keyReady()) {
321 throw new CryptoException("Key not Ready");
322 }
323 try {
324 final Cipher cipher = Cipher.getInstance(getAlgorithm());
325 cipher.init(Cipher.DECRYPT_MODE, secretKey);
326 return cipher.doFinal(ciphertext);
327 } catch (final Exception e) {
328 logger.warn("Decrypt Error", e);
329 throw e;
330 }
331 }
332
333
334
335
336
337
338
339
340
341
342 public final String decryptInString(final byte[] ciphertext)
343 throws Exception {
344 return new String(decrypt(ciphertext), WaarpStringUtils.UTF8);
345 }
346
347
348
349
350
351
352
353
354
355
356
357
358 public final byte[] decryptHexInBytes(final String ciphertext)
359 throws Exception {
360 final byte[] arrayBytes = decodeHex(ciphertext);
361 return decrypt(arrayBytes);
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375 public final byte[] decryptHexInBytes(final byte[] ciphertext)
376 throws Exception {
377 final byte[] arrayBytes =
378 decodeHex(new String(ciphertext, WaarpStringUtils.UTF8));
379 return decrypt(arrayBytes);
380 }
381
382
383
384
385
386
387
388
389
390
391
392 public final String decryptHexInString(final String ciphertext)
393 throws Exception {
394 return new String(decryptHexInBytes(ciphertext), WaarpStringUtils.UTF8);
395 }
396
397
398
399
400
401
402
403
404
405
406
407 public final String decryptHexInString(final byte[] ciphertext)
408 throws Exception {
409 return new String(decryptHexInBytes(ciphertext), WaarpStringUtils.UTF8);
410 }
411
412
413
414
415
416
417
418
419
420
421 public final byte[] decryptHexFile(final File file) throws Exception {
422 if (file.length() > Integer.MAX_VALUE) {
423 throw new IOException(
424 "File too big to be decoded into an array of bytes");
425 }
426 byte[] byteKeys = new byte[(int) file.length()];
427 FileInputStream inputStream = null;
428 DataInputStream dis = null;
429 try {
430 inputStream = new FileInputStream(file);
431 dis = new DataInputStream(inputStream);
432 dis.readFully(byteKeys);
433 FileUtils.close(dis);
434 final String skey = new String(byteKeys, WaarpStringUtils.UTF8);
435
436 byteKeys = decryptHexInBytes(skey);
437 return byteKeys;
438 } finally {
439 FileUtils.close(dis);
440 FileUtils.close(inputStream);
441 }
442 }
443
444
445
446
447
448
449 public final byte[] decodeHex(final String encoded) {
450 return FilesystemBasedDigest.getFromHex(encoded);
451 }
452
453
454
455
456
457
458 public final String encodeHex(final byte[] bytes) {
459 return FilesystemBasedDigest.getHex(bytes);
460 }
461 }