KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > jcetaglib > lib > Crypt


1 /*
2   Name: Crypt.java
3   Licensing: LGPL
4
5   API: Sun (http://java.sun.com) JCE 1.2.2 API (cleanroom implementation by Bouncy Castle)
6   Provider: Bouncy Castle (http://www.bouncycastle.org)
7
8   Disclaimer:
9
10   COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND,
11   EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE
12   IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
13   RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE
14   PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR)
15   ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
16   CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED
17   HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
18
19   (C) Copyright 2003 Gert Van Ham
20 */

21
22 package net.sourceforge.jcetaglib.lib;
23
24 import net.sourceforge.jcetaglib.exceptions.CryptoException;
25 import net.sourceforge.jcetaglib.exceptions.KeystoreException;
26 import org.bouncycastle.jce.provider.BouncyCastleProvider;
27 import org.bouncycastle.util.encoders.Base64;
28
29 import javax.crypto.Cipher;
30 import javax.crypto.CipherInputStream;
31 import javax.crypto.CipherOutputStream;
32 import javax.crypto.spec.IvParameterSpec;
33 import java.io.*;
34 import java.security.Key JavaDoc;
35 import java.security.SecureRandom JavaDoc;
36 import java.security.Security JavaDoc;
37
38 /**
39  * Symmetric block/stream cipher encryption & decryption routines for use with BouncyCastle JCE provider
40  *
41  * @author Gert Van Ham
42  * @author hamgert@users.sourceforge.net
43  * @author http://jcetaglib.sourceforge.net
44  * @version $Id: Crypt.java,v 1.3 2004/04/15 07:28:25 hamgert Exp $
45  */

46 public class Crypt {
47
48     // buffersizes in bytes
49
private static int BUFFERSIZE_TEXT = 64;
50     private static int BUFFERSIZE_FILE = 8192;
51
52     /**
53      * Encrypts a message with a symmetric key
54      *
55      * @param text the message to encrypt
56      * @param keyfile keyfile(name)
57      * @param passphrase the passphrase for the keystore
58      * @param algorithm encryption algorithm (e.g. "Rijndael")
59      * @param mode encryption mode (e.g. "CBC")
60      * @param padding padding scheme (e.g."PKCS7Padding")
61      * @param seed seed for SecureRandom (optional)
62      * @return encrypted message in BASE64
63      * @throws CryptoException for encryption errors
64      * @throws KeystoreException when keystore could not be loaded
65      */

66     public static StringBuffer JavaDoc encrypt(StringBuffer JavaDoc text
67                                        , String JavaDoc keyfile
68                                        , StringBuffer JavaDoc passphrase
69                                        , String JavaDoc algorithm
70                                        , String JavaDoc mode
71                                        , String JavaDoc padding
72                                        , byte[] seed) throws CryptoException, KeystoreException {
73
74         // read secret key
75
Key JavaDoc secretKey = Keystore.loadKey(algorithm, keyfile, passphrase);
76
77         // encrypt text
78
return encrypt(text, secretKey, algorithm, mode, padding, seed);
79     }
80
81     /**
82      * Encrypts a message with a symmetric key
83      *
84      * @param text the message to encrypt
85      * @param secretKey the secret key
86      * @param algorithm encryption algorithm (e.g. "Rijndael")
87      * @param mode encryption mode (e.g. "CBC")
88      * @param padding padding scheme (e.g."PKCS7Padding")
89      * @param seed seed for SecureRandom (optional)
90      * @return encrypted message in BASE64
91      * @throws CryptoException for encryption errors
92      */

93     public static StringBuffer JavaDoc encrypt(StringBuffer JavaDoc text
94                                        , Key JavaDoc secretKey
95                                        , String JavaDoc algorithm
96                                        , String JavaDoc mode
97                                        , String JavaDoc padding
98                                        , byte[] seed) throws CryptoException {
99
100         ByteArrayOutputStream bao = null;
101         DataOutputStream dao = null;
102
103         try {
104             bao = new ByteArrayOutputStream();
105             dao = new DataOutputStream(bao);
106
107             // encrypt text
108
encrypt(new ByteArrayInputStream(text.toString().getBytes()), dao, secretKey, algorithm, mode, padding, seed, BUFFERSIZE_TEXT);
109             return new StringBuffer JavaDoc(new String JavaDoc(Base64.encode(bao.toByteArray())));
110         } catch (IOException ioe) {
111             ioe.printStackTrace();
112             throw new CryptoException(ioe.getMessage());
113         } finally {
114             if (dao != null) {
115                 // close outputstream
116
try {
117                     dao.close();
118                 } catch (IOException e) {
119                     ;
120                 }
121             }
122         }
123     }
124
125     /**
126      * Encrypts a file with a symmetric key
127      *
128      * @param file the file to encrypt
129      * @param newfile the encrypted file
130      * @param keyfile keyfile(name)
131      * @param passphrase the passphrase for the keystore
132      * @param algorithm encryption algorithm (e.g. "Rijndael")
133      * @param mode encryption mode (e.g. "CBC")
134      * @param padding padding scheme (e.g."PKCS7Padding")
135      * @param seed seed for SecureRandom (optional)
136      * @throws CryptoException encryption errors
137      * @throws IOException I/O errors
138      * @throws KeystoreException when keystore could not be loaded
139      */

140     public static void encryptFile(String JavaDoc file
141                                    , String JavaDoc newfile
142                                    , String JavaDoc keyfile
143                                    , StringBuffer JavaDoc passphrase
144                                    , String JavaDoc algorithm
145                                    , String JavaDoc mode
146                                    , String JavaDoc padding
147                                    , byte[] seed) throws CryptoException, IOException, KeystoreException {
148
149         FileInputStream fis = null;
150         FileOutputStream fos = null;
151         DataOutputStream dao = null;
152
153         try {
154             fis = new FileInputStream(file);
155
156             fos = new FileOutputStream(newfile);
157             dao = new DataOutputStream(fos);
158
159             // read secret key
160
Key JavaDoc secretKey = Keystore.loadKey(algorithm, keyfile, passphrase);
161
162             // encrypt file
163
encrypt(fis, dao, secretKey, algorithm, mode, padding, seed, BUFFERSIZE_FILE);
164
165         } catch (IOException ioe) {
166             ioe.printStackTrace();
167             throw new IOException(ioe.getMessage());
168         } finally {
169             if (dao != null) {
170                 // close outputstream
171
try {
172                     dao.close();
173                 } catch (IOException e) {
174                     ;
175                 }
176             }
177             if (fis != null) {
178                 // close outputstream
179
try {
180                     fis.close();
181                 } catch (IOException e) {
182                     ;
183                 }
184             }
185         }
186     }
187
188     /**
189      * Encrypts any inputstream with a symmetric key
190      *
191      * @param is the inputstream to encrypt
192      * @param daos the encrypted outputstream
193      * @param secretKey the secret key
194      * @param algorithm encryption algorithm (e.g. "Rijndael")
195      * @param mode encryption mode (e.g. "CBC")
196      * @param padding padding scheme (e.g."PKCS7Padding")
197      * @param seed seed for SecureRandom (optional)
198      * @param bufferlength buffer length in bytes
199      * @exception CryptoException for encryption errors
200      * @exception IOException I/O errors
201      **/

202     public static void encrypt(InputStream is
203                                , DataOutputStream daos
204                                , Key JavaDoc secretKey
205                                , String JavaDoc algorithm
206                                , String JavaDoc mode
207                                , String JavaDoc padding
208                                , byte[] seed
209                                , int bufferlength)
210             throws CryptoException, IOException {
211
212         IvParameterSpec spec = null; // initialization vector
213
byte[] iv = null; // initialization vector as byte[]
214
Cipher cipher = null;
215         CipherOutputStream cStr = null;
216
217         try {
218             if (algorithm.equalsIgnoreCase("RC4")) {
219                 // create a stream cipher object (ignore mode & padding)
220
cipher = Cipher.getInstance("RC4");
221             } else {
222                 // create a block cipher object: ("algorithm/mode/padding", provider)
223
cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
224             }
225
226             if (mode.equalsIgnoreCase("ECB") || algorithm.equalsIgnoreCase("RC4")) {
227                 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
228             } else {
229                 // These modes need an iv with a valid block size in order
230
// to be used.
231
SecureRandom JavaDoc sr = Seed.getSecureRandom(seed);
232                 // allocate memory for iv.
233
iv = new byte[cipher.getBlockSize()];
234                 // Get next bytes from the PRNG.
235
sr.nextBytes(iv);
236                 // create the IV class.
237
spec = new IvParameterSpec(iv);
238
239                 cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);
240             }
241
242             cStr = new CipherOutputStream(daos, cipher);
243
244             // first, write the IV to the file
245
if (iv != null)
246                 daos.write(iv);
247
248             // Read input bytes into buffer and run them through the
249
// cipher stream.
250
byte[] buffer = new byte[bufferlength];
251             int length = 0;
252             while ((length = is.read(buffer)) != -1)
253                 cStr.write(buffer, 0, length);
254
255         } catch (IOException ioe) {
256             ioe.printStackTrace();
257             throw new IOException(ioe.getMessage());
258         } catch (Exception JavaDoc ex) {
259             ex.printStackTrace();
260             throw new CryptoException(ex.getMessage());
261         } finally {
262             if (cStr != null) {
263                 try {
264                     cStr.close();
265                 } catch (IOException ioe) {
266                     ;
267                 }
268             }
269         }
270     }
271
272     /**
273      * Decrypts a message with a symmetric key
274      *
275      * @param text the message to decrypt in BASE64 format
276      * @param keyfile keyfile(name)
277      * @param passphrase the passphrase for the keystore
278      * @param algorithm encryption algorithm (e.g. "Rijndael")
279      * @param mode encryption mode (e.g. "CBC")
280      * @param padding padding scheme (e.g."PKCS7Padding")
281      * @return deciphered message
282      * @throws CryptoException for encryption errors
283      * @throws KeystoreException when keystore could not be loaded
284      */

285     public static StringBuffer JavaDoc decrypt(StringBuffer JavaDoc text
286                                        , String JavaDoc keyfile
287                                        , StringBuffer JavaDoc passphrase
288                                        , String JavaDoc algorithm
289                                        , String JavaDoc mode
290                                        , String JavaDoc padding) throws CryptoException, KeystoreException {
291
292         // read secret key
293
Key JavaDoc secretKey = Keystore.loadKey(algorithm, keyfile, passphrase);
294
295         return decrypt(text, secretKey, algorithm, mode, padding);
296     }
297
298     /**
299      * Decrypts a message with a symmetric key
300      *
301      * @param text the message to decrypt in BASE64 format
302      * @param secretKey the secret key
303      * @param algorithm encryption algorithm (e.g. "Rijndael")
304      * @param mode encryption mode (e.g. "CBC")
305      * @param padding padding scheme (e.g."PKCS7Padding")
306      * @return deciphered message
307      * @throws CryptoException for encryption errors
308      */

309     public static StringBuffer JavaDoc decrypt(StringBuffer JavaDoc text
310                                        , Key JavaDoc secretKey
311                                        , String JavaDoc algorithm
312                                        , String JavaDoc mode
313                                        , String JavaDoc padding) throws CryptoException {
314
315         ByteArrayOutputStream bao = null;
316         DataOutputStream dao = null;
317
318         try {
319             bao = new ByteArrayOutputStream();
320             dao = new DataOutputStream(bao);
321
322             // decrypt
323
decrypt(new ByteArrayInputStream(Base64.decode(text.toString())), dao, secretKey, algorithm, mode, padding, BUFFERSIZE_TEXT);
324
325             return new StringBuffer JavaDoc(new String JavaDoc(bao.toByteArray()));
326
327         } catch (IOException ioe) {
328             ioe.printStackTrace();
329             throw new CryptoException(ioe.getMessage());
330         } finally {
331             if (dao != null) {
332                 // close outputstream
333
try {
334                     dao.close();
335                 } catch (IOException e) {
336                     ;
337                 }
338             }
339         }
340     }
341
342     /**
343      * Decrypts a file with a symmetric key
344      *
345      * @param file the file to decrypt
346      * @param newfile the deciphered file
347      * @param keyfile keyfile(name)
348      * @param passphrase the passphrase for the keystore
349      * @param algorithm encryption algorithm (e.g. "Rijndael")
350      * @param mode encryption mode (e.g. "CBC")
351      * @param padding padding scheme (e.g."PKCS7Padding")
352      * @throws CryptoException encryption errors
353      * @throws IOException I/O errors
354      */

355     public static void decryptFile(String JavaDoc file
356                                    , String JavaDoc newfile
357                                    , String JavaDoc keyfile
358                                    , StringBuffer JavaDoc passphrase
359                                    , String JavaDoc algorithm
360                                    , String JavaDoc mode
361                                    , String JavaDoc padding) throws CryptoException, KeystoreException, IOException {
362
363         FileInputStream fis = null;
364         FileOutputStream fos = null;
365         DataOutputStream dao = null;
366
367         try {
368             fis = new FileInputStream(file);
369
370             fos = new FileOutputStream(newfile);
371             dao = new DataOutputStream(fos);
372
373             // read secret key
374
Key JavaDoc secretKey = Keystore.loadKey(algorithm, keyfile, passphrase);
375
376             // decrypt file
377
decrypt(fis, dao, secretKey, algorithm, mode, padding, BUFFERSIZE_FILE);
378
379         } catch (IOException ioe) {
380             ioe.printStackTrace();
381             throw new IOException(ioe.getMessage());
382         } finally {
383             if (dao != null) {
384                 // close outputstream
385
try {
386                     dao.close();
387                 } catch (IOException e) {
388                     ;
389                 }
390             }
391             if (fis != null) {
392                 // close inputstream
393
try {
394                     fis.close();
395                 } catch (IOException e) {
396                     ;
397                 }
398             }
399         }
400     }
401
402     /**
403      * Decrypts any inputstream with a symmetric key
404      *
405      * @param is the inputstream to decrypt
406      * @param daos the deciphered outputstream
407      * @param secretKey the secret key
408      * @param algorithm String encryption algorithm (e.g. "Rijndael")
409      * @param mode String encryption mode (e.g. "CBC")
410      * @param padding String padding scheme (e.g."PKCS7Padding")
411      * @param bufferlength buffer length in bytes
412      * @exception CryptoException for encryption errors
413      * @exception IOException I/O errors
414      **/

415     public static void decrypt(InputStream is
416                                , DataOutputStream daos
417                                , Key JavaDoc secretKey
418                                , String JavaDoc algorithm
419                                , String JavaDoc mode
420                                , String JavaDoc padding
421                                , int bufferlength)
422             throws CryptoException, IOException {
423
424         Cipher cipher = null;
425         IvParameterSpec spec = null; // initialization vector
426
byte[] iv = null; // initialization vector as byte[]
427
//Key secretKey = null;
428
CipherInputStream cStr = null;
429
430         try {
431             Security.addProvider(new BouncyCastleProvider());
432
433             if (algorithm.equalsIgnoreCase("RC4")) {
434                 // create a stream cipher object (ignore mode & padding)
435
cipher = Cipher.getInstance("RC4");
436             } else {
437                 // create a block cipher object: ("algorithm/mode/padding", provider)
438
cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding, "BC");
439             }
440
441             if (mode.equalsIgnoreCase("ECB") || algorithm.equalsIgnoreCase("RC4")) {
442                 cipher.init(Cipher.DECRYPT_MODE, secretKey);
443             } else {
444                 // read IV.
445
iv = new byte[cipher.getBlockSize()];
446                 is.read(iv);
447
448                 spec = new IvParameterSpec(iv);
449                 cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
450             }
451
452             cStr = new CipherInputStream(is, cipher);
453
454             // Read bytes and run them through cipher and store them to
455
// file back again.
456
byte[] buffer = new byte[bufferlength];
457             int length = 0;
458             while ((length = cStr.read(buffer)) != -1)
459                 daos.write(buffer, 0, length);
460
461         } catch (IOException ioe) {
462             ioe.printStackTrace();
463             throw new IOException(ioe.getMessage());
464         } catch (Exception JavaDoc ex) {
465             ex.printStackTrace();
466             throw new CryptoException(ex.getMessage());
467         } finally {
468             if (cStr != null) {
469                 try {
470                     cStr.close();
471                 } catch (IOException ioe) {
472                     ;
473                 }
474             }
475         }
476     }
477 }
478
Popular Tags