KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > crypto > FileCipherManager


1 package SnowMailClient.crypto;
2
3 import snow.utils.storage.*;
4 import snow.crypto.*;
5 import snow.Language.Language;
6
7 import java.security.*;
8 import java.security.spec.*;
9 import javax.crypto.spec.*;
10 import javax.crypto.*;
11 import java.io.*;
12 import java.util.zip.*;
13 import java.util.*;
14 import javax.swing.*;
15
16
17 /** contain EncipherFile and DecipherFile
18 */

19 public final class FileCipherManager
20 {
21   private static FileCipherManager instance = null;
22
23   private FileCipherManager()
24   {
25   }
26
27   public static FileCipherManager getInstance()
28   {
29     if(instance==null)
30     {
31       instance = new FileCipherManager();
32     }
33     return instance;
34   }
35
36
37   public void encipherVectorToFile(Vector<Object JavaDoc> v, File out, SecretKey key) throws Exception JavaDoc
38   {
39      encipherVectorWithHeadToFile(new Vector<Object JavaDoc>(), new Vector<Object JavaDoc>(), v, out, key);
40   }
41
42   /** the head, small should be used for performance reasons, for example
43      to store an index describing the content.
44   */

45   public void encipherVectorWithHeadToFile(Vector<Object JavaDoc> uncipheredHead, Vector<Object JavaDoc> cipheredHead, Vector<Object JavaDoc> v, File out, SecretKey key) throws Exception JavaDoc
46   {
47
48     Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
49     cipher.init(Cipher.ENCRYPT_MODE, key);
50
51     FileOutputStream fos = null;
52     DataOutputStream dos = null;
53     GZIPOutputStream zos = null;
54     CipherOutputStream cos = null;
55     try
56     {
57       fos = new FileOutputStream(out);
58       dos = new DataOutputStream(fos);
59       dos.writeInt(3);
60       dos.writeUTF("Blowfish");
61       dos.writeInt(key.getEncoded().length);
62       SecretKeyID ski = SecretKeyUtilities.computeSignature(key);
63       dos.write(ski.signature,0,4);
64
65       cos = new CipherOutputStream(dos, cipher);
66       zos = new GZIPOutputStream(cos);
67
68       DataOutputStream dos2 = new DataOutputStream(zos);
69       VectorUtils.vectorToStream(dos2, cipheredHead);
70       VectorUtils.vectorToStream(dos2, v);
71
72       zos.close();
73     }
74     catch(Exception JavaDoc e)
75     {
76       throw e;
77     }
78     finally
79     {
80       if(fos!=null) fos.close();
81     }
82   }
83
84
85   /** @return the keyID of the enciphered file
86   */

87   public SecretKeyID getKeyIDFromFile(File in) throws Exception JavaDoc
88   {
89     FileInputStream fis = null;
90     DataInputStream dis = null;
91     try
92     {
93        fis = new FileInputStream(in);
94        dis = new DataInputStream(fis);
95        // header read
96
int version = dis.readInt();
97        if(version==1)
98        {
99           String JavaDoc algo = dis.readUTF();
100           if(algo.equalsIgnoreCase("Blowfish"))
101           {
102             throw new Exception JavaDoc(Language.translate("Bad encryption algorithm %",algo));
103           }
104           int keyLength = dis.readInt();
105           byte[] sign = new byte[4];
106           dis.readFully(sign,0,4);
107           dis.close();
108
109           SecretKeyID ski = new SecretKeyID(sign, keyLength);
110           if( keyLength>20 )
111           {
112             throw new Exception JavaDoc(Language.translate("Bad key length found %",""+keyLength));
113           }
114           return ski;
115        }
116        else if(version>=2)
117        {
118           String JavaDoc algo = dis.readUTF();
119           int keyLength = dis.readInt();
120           byte[] sign = new byte[4];
121           dis.readFully(sign,0,4);
122           dis.close();
123
124           SecretKeyID ski = new SecretKeyID(sign, keyLength);
125           return ski;
126        }
127        else
128        {
129          throw new Exception JavaDoc(Language.translate("Bad version %",""+version));
130        }
131     }
132     catch(Exception JavaDoc e)
133     {
134       throw e;
135     }
136     finally
137     {
138        if(fis!=null) fis.close();
139     }
140
141   }
142
143
144   /** simply decipher the file, asking for the key
145   */

146   public Vector<Object JavaDoc> decipherVectorFromFile_ASK_KEY_IF_NEEDED(
147                     File file,
148                     Object JavaDoc frameOrDialog_owner,
149                     String JavaDoc title, String JavaDoc explanation
150                 ) throws Exception JavaDoc
151   {
152
153       SecretKeyID keyID = null;
154       try
155       {
156           keyID = this.getKeyIDFromFile(file);
157       }
158       catch(Exception JavaDoc e)
159       {
160          // no key ID in the file...
161
// try the old version 0
162
System.out.println("No key for "+file.getAbsolutePath()+" trying old version");
163          Vector<Object JavaDoc> v = FileUtils.loadVectorFromFile(file);
164          return v;
165       }
166
167       SecretKey sk = SecretKeyManager.getInstance().getKey(keyID);
168
169       if(sk==null)
170       {
171          System.out.println("No keyID for "+file.getAbsolutePath());
172
173          PassphraseDialog pd = null;
174          if(frameOrDialog_owner instanceof JFrame)
175          {
176            pd = new PassphraseDialog((JFrame) frameOrDialog_owner, title, true, keyID, file, explanation);
177          }
178          else
179          {
180            pd = new PassphraseDialog((JDialog) frameOrDialog_owner, title, true, keyID, file, explanation);
181          }
182
183          if(pd.wasCancelled())
184          {
185            throw new BadPasswordException(Language.translate("Password not entered"));
186          }
187
188          if(!pd.matchesID())
189          {
190            throw new BadPasswordException(Language.translate("Bad password"));
191          }
192
193          // read the key and add it to the collection
194
sk = pd.getKey();
195          SecretKeyManager.getInstance().addKey(sk);
196
197       }
198
199       try
200       {
201          Vector<Object JavaDoc> v = FileCipherManager.getInstance().decipherVectorFromFile(file,
202                 sk);
203          //System.out.println(""+file.getAbsolutePath()+" read");
204
return v;
205       }
206       catch(Exception JavaDoc ee)
207       {
208          throw ee;
209       }
210   }
211
212
213   /** simply decipher the file with the given key
214   */

215   public static Vector<Object JavaDoc> decipherVectorFromFile(File in, SecretKey key) throws Exception JavaDoc
216   {
217     final Vector<Object JavaDoc> v = new Vector<Object JavaDoc>();
218     final Vector<Object JavaDoc> head = new Vector<Object JavaDoc>();
219
220     FileInputStream fis = null;
221     DataInputStream dis = null;
222     CipherInputStream cis = null;
223     GZIPInputStream zis = null;
224
225     try
226     {
227       fis = new FileInputStream(in);
228       //BufferedInputStream bis = new BufferedInputStream(fis, 65536*32);
229
dis = new DataInputStream(fis);
230
231       // (clear) header read
232
//
233
int version = dis.readInt();
234       if(version==1)
235       {
236         // old version 1 was a static pass
237
String JavaDoc algo = dis.readUTF();
238         int keyLength = dis.readInt();
239         byte[] sign = new byte[4];
240         dis.readFully(sign,0,4);
241         SecretKeyID ski = new SecretKeyID(sign, keyLength);
242         key = SecretKeyManager.getInstance().getDefaultKeyVersion1_();
243       }
244       else if(version>=2)
245       {
246         // custom pass (or default, if not set...)
247
String JavaDoc algo = dis.readUTF();
248         int keyLength = dis.readInt();
249         byte[] sign = new byte[4];
250         dis.readFully(sign,0,4);
251         SecretKeyID ski = new SecretKeyID(sign, keyLength);
252         if(!SecretKeyUtilities.computeSignature(key).equals(ski))
253         {
254           throw new BadPasswordException(Language.translate("Bad key"));
255         }
256       }
257       else
258       {
259         throw new Exception JavaDoc("Bad file version "+version);
260       }
261
262       // read cipher vector part
263
//
264

265       long t = System.currentTimeMillis();
266       Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
267       cipher.init(Cipher.DECRYPT_MODE, key);
268
269       cis = new CipherInputStream(dis, cipher);
270       zis = new GZIPInputStream(cis);
271       DataInputStream dis2 = new DataInputStream(zis);
272       if(version>=3)
273       {
274         VectorUtils.streamToVector(dis2, head);
275         //System.out.println("Head read, length="+head.size());
276
}
277       VectorUtils.streamToVector(dis2, v);
278
279       long t2 = System.currentTimeMillis();
280       //System.out.println("Read in "+(t2-t)/1000+" sec");
281

282
283       zis.close();
284     }
285     catch(Exception JavaDoc e)
286     {
287       throw e;
288     }
289     finally
290     {
291       if(fis!=null) fis.close();
292     }
293     return v;
294   }
295
296
297   /** Decipher the file with the given key, read only the header
298   */

299   public Vector<Object JavaDoc> decipherVectorHeaderFromFile(File in, SecretKey key) throws Exception JavaDoc
300   {
301     final Vector<Object JavaDoc> head = new Vector<Object JavaDoc>();
302
303     FileInputStream fis = null;
304     DataInputStream dis = null;
305     CipherInputStream cis = null;
306     GZIPInputStream zis = null;
307
308     try
309     {
310       fis = new FileInputStream(in);
311       dis = new DataInputStream(fis);
312
313       // (clear) header read
314
//
315
int version = dis.readInt();
316       if(version==1)
317       {
318         // old version 1 was a static pass
319
String JavaDoc algo = dis.readUTF();
320         int keyLength = dis.readInt();
321         byte[] sign = new byte[4];
322         dis.readFully(sign,0,4);
323         //not used... SecretKeyID ski = new SecretKeyID(sign, keyLength);
324
key = SecretKeyManager.getInstance().getDefaultKeyVersion1_();
325       }
326       else if(version>=2)
327       {
328         // custom pass (or default, if not set...)
329
String JavaDoc algo = dis.readUTF();
330         int keyLength = dis.readInt();
331         byte[] sign = new byte[4];
332         dis.readFully(sign,0,4);
333         SecretKeyID ski = new SecretKeyID(sign, keyLength);
334         if(!SecretKeyUtilities.computeSignature(key).equals(ski))
335         {
336           throw new BadPasswordException(Language.translate("Bad key"));
337         }
338       }
339       else
340       {
341         throw new Exception JavaDoc("Bad file version "+version);
342       }
343
344       // read cipher vector part
345
//
346

347       Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding");
348       cipher.init(Cipher.DECRYPT_MODE, key);
349
350       cis = new CipherInputStream(dis, cipher);
351       zis = new GZIPInputStream(cis);
352       DataInputStream dis2 = new DataInputStream(zis);
353       if(version>=3)
354       {
355         VectorUtils.streamToVector(dis2, head);
356         //System.out.println("Head read, length="+head.size());
357
}
358       zis.close();
359     }
360     catch(Exception JavaDoc e)
361     {
362       throw e;
363     }
364     finally
365     {
366       if(fis!=null) fis.close();
367     }
368     return head;
369   }
370
371 } // FileCipherManager
Popular Tags