KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > lightcrypto > Key


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

20
21 package net.sourceforge.lightcrypto;
22
23 import org.bouncycastle.crypto.*;
24 import org.bouncycastle.crypto.digests.SHA1Digest;
25 import org.bouncycastle.crypto.engines.TwofishEngine;
26 import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
27 import org.bouncycastle.crypto.modes.CBCBlockCipher;
28 import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
29
30 import java.io.ByteArrayOutputStream JavaDoc;
31 import java.io.FileInputStream JavaDoc;
32 import java.io.FileNotFoundException JavaDoc;
33 import java.io.FileOutputStream JavaDoc;
34 import java.security.SecureRandom JavaDoc;
35
36 /**
37  * Class to generate and read symmetric (shared) keys with the Bouncycastle lightweight API.
38  * Keys are wrapped with PBE (Password-Based Encryption)
39  *
40  * @author Gert Van Ham
41  * @author hamgert@users.sourceforge.net
42  * @author http://jcetaglib.sourceforge.net
43  * @version $Id: Key.java,v 1.2 2003/10/05 11:41:29 hamgert Exp $
44  */

45
46 public class Key {
47     private static int SecKeystoreCount = 100;
48     private static int SecKeystoreKeylength = 256;
49     private static int SecKeylength = 128;
50
51     /**
52      * Constructor
53      **/

54     public Key() {
55     }
56
57     /**
58      * Generates a symmetric key, wraps it up and stores it in a file
59      *
60      * @param file the filename to store the symmetric key
61      * @param passphrase the passphrase for the symmetric key
62      * @exception CryptoException for all errors
63      **/

64     public static void generatekey(
65             String JavaDoc file
66             , StringBuffer JavaDoc passphrase) throws CryptoException {
67         generatekey(file, passphrase, null);
68     }
69
70     /**
71      * Generates a symmetric key, wraps it up and stores it in a file
72      *
73      * @param file the filename to store the symmetric key
74      * @param passphrase the passphrase for the symmetric key
75      * @param seed the seed for SecureRandom (used for generating the PBE salt)
76      * @exception CryptoException for all errors
77      **/

78     public static void generatekey(
79             String JavaDoc file
80             , StringBuffer JavaDoc passphrase
81             , StringBuffer JavaDoc seed
82             ) throws CryptoException {
83
84         FileOutputStream JavaDoc fos = null;
85         byte[] key = null;
86         byte[] wrappedkey = null;
87         byte[] newkey = null;
88
89         try {
90             SecureRandom JavaDoc sr = new SecureRandom JavaDoc();
91
92             // set seed if available
93
if (seed != null && !seed.equals("")) {
94                 sr.setSeed(seed.toString().getBytes());
95                 // clean the seed from memory
96
Clean.blank(seed);
97             }
98
99             KeyGenerationParameters keygen = new KeyGenerationParameters(sr, SecKeylength);
100             CipherKeyGenerator cipherkey = new CipherKeyGenerator();
101             cipherkey.init(keygen);
102
103             // generate the key
104
key = cipherkey.generateKey();
105
106             // create random salt
107
byte[] randomsalt = new byte[8];
108             sr.nextBytes(randomsalt);
109
110             // create the PBE cipher
111
PBEParametersGenerator generator = new PKCS12ParametersGenerator(new SHA1Digest());
112             generator.init(PBEParametersGenerator.PKCS12PasswordToBytes(passphrase.toString().toCharArray()), randomsalt, SecKeystoreCount);
113
114             // clean the passphrase from memory
115
Clean.blank(passphrase);
116
117             TwofishEngine blockCipher = new TwofishEngine();
118             CBCBlockCipher cbcCipher = new CBCBlockCipher(blockCipher);
119             BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcCipher);
120
121             CipherParameters param = generator.generateDerivedParameters(SecKeystoreKeylength,128);
122
123             // encrypt the symmetric key with PBE
124
cipher.init(true, param);
125
126             int outputLen = 0;
127             wrappedkey = new byte[cipher.getOutputSize(key.length)];
128             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
129
130             // process cipher
131
outputLen = cipher.processBytes(key, 0, key.length, wrappedkey, 0);
132
133             if (outputLen > 0) {
134                 baos.write(wrappedkey, 0, outputLen);
135             }
136
137             // process last bytes
138
outputLen = cipher.doFinal(wrappedkey, 0);
139
140             if (outputLen > 0) {
141                 baos.write(wrappedkey, 0, outputLen);
142             }
143
144             // save the wrapped key to disk
145
fos = new FileOutputStream JavaDoc(file);
146             fos.write(randomsalt);
147             fos.write(baos.toByteArray());
148             fos.close();
149
150             baos.close();
151         } catch (Exception JavaDoc ex) {
152             ex.printStackTrace();
153             throw new CryptoException(ex.getMessage());
154         } finally {
155             // close the outputstream
156
if (fos != null) {
157                 try {
158                     fos.close();
159                 } catch (Exception JavaDoc e) {
160                     ;
161                 }
162                 fos = null;
163             }
164
165             // clean sensitive information from memory
166
Clean.blank(passphrase);
167             if (seed != null) {
168                 Clean.blank(seed);
169                 seed = null;
170             }
171             if (key != null) {
172                 Clean.blank(key);
173                 key = null;
174             }
175             if (wrappedkey != null) {
176                 Clean.blank(wrappedkey);
177                 wrappedkey = null;
178             }
179             if (newkey != null) {
180                 Clean.blank(wrappedkey);
181                 wrappedkey = null;
182             }
183         }
184     }
185
186     /**
187      * Load a symmetric key from the file, unwrap it and return the key bytes
188      *
189      * @param file the filename where the symmetric key is stored
190      * @param passphrase the passphrase for the symmetric key
191      * @return the key as a SafeObject
192      * @exception KeyException when the key could not be loaded
193      * @exception CryptoException for all errors
194      **/

195     public static SafeObject loadkey(
196             String JavaDoc file
197             , StringBuffer JavaDoc passphrase) throws CryptoException, KeyException {
198
199         FileInputStream JavaDoc fInput = null;
200         byte[] keybytes = null;
201
202         try {
203             fInput = new FileInputStream JavaDoc(file);
204
205             // read the salt
206
byte[] randomsalt = new byte[8];
207             fInput.read(randomsalt);
208
209             // read the wrapped key
210
ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
211             int i = 0;
212             while ((i = fInput.read()) != -1) {
213                 baos.write(i);
214             }
215             fInput.close();
216             byte[] wrappedkey = baos.toByteArray();
217             baos.close();
218
219             // Create the PBE cipher
220
PBEParametersGenerator generator = new PKCS12ParametersGenerator(new SHA1Digest());
221             generator.init(PBEParametersGenerator.PKCS12PasswordToBytes(passphrase.toString().toCharArray()), randomsalt, SecKeystoreCount);
222
223             // clean the passphrase from memory
224
Clean.blank(passphrase);
225
226             TwofishEngine blockCipher = new TwofishEngine();
227             CBCBlockCipher cbcCipher = new CBCBlockCipher(blockCipher);
228             BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(cbcCipher);
229
230             CipherParameters param = generator.generateDerivedParameters(SecKeystoreKeylength,128);
231
232             // decrypt the wrapped key with PBE
233
cipher.init(false, param);
234
235             int outputLen = 0;
236             keybytes = new byte[cipher.getOutputSize(wrappedkey.length)];
237
238             ByteArrayOutputStream JavaDoc baos2 = new ByteArrayOutputStream JavaDoc();
239
240             // process cipher
241
outputLen = cipher.processBytes(wrappedkey, 0, wrappedkey.length, keybytes, 0);
242
243             if (outputLen > 0) {
244                 baos2.write(keybytes, 0, outputLen);
245             }
246
247             // process last bytes
248
outputLen = cipher.doFinal(keybytes, 0);
249
250             if (outputLen > 0) {
251                 baos2.write(keybytes, 0, outputLen);
252             }
253
254             SafeObject sf = new SafeObject();
255             sf.setText(baos2.toByteArray());
256
257             baos2.close();
258
259             return sf;
260         } catch (FileNotFoundException JavaDoc fnfe) {
261             throw new KeyException("Unable to load key from keystore \"" + file + "\" - keystore could not be found");
262         } catch (Exception JavaDoc ex) {
263             ex.printStackTrace();
264             throw new CryptoException(ex.getMessage());
265         } finally {
266             // close the inputstream
267
if (fInput != null) {
268                 try {
269                     fInput.close();
270                 } catch (Exception JavaDoc e) {
271                     ;
272                 }
273                 fInput = null;
274             }
275
276             // clean sensitive information from memory
277
Clean.blank(passphrase);
278         }
279     }
280
281     /**
282      * Sets the PBE iteration count (default = 100)
283      *
284      * @param secKeystoreCount iteration count
285      **/

286     public void setSecKeystoreCount(int secKeystoreCount) {
287         SecKeystoreCount = secKeystoreCount;
288     }
289
290     /**
291      * Sets the PBE key length (default = 256)
292      *
293      * @param secKeystoreKeylength PBE key length in bits
294      **/

295     public static void setSecKeystoreKeylength(int secKeystoreKeylength) {
296         SecKeystoreKeylength = secKeystoreKeylength;
297     }
298
299     /**
300      * Sets the AES keybits (default = 256)
301      *
302      * @param secKeylength key length in bits
303      **/

304     public void setSecKeylength(int secKeylength) {
305         SecKeylength = secKeylength;
306     }
307 }
Popular Tags