View Javadoc

1   package org.apache.fulcrum.jce.crypto;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileOutputStream;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.OutputStream;
30  import java.security.GeneralSecurityException;
31  
32  /**
33   * Helper class to provde generic functions to work with CryptoStreams.
34   *
35   * The code uses parts from Markus Hahn's Blowfish library found at
36   * http://blowfishj.sourceforge.net/
37   *
38   * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
39   * @author <a href="mailto:maakus@earthlink.net">Markus Hahn</a>
40   */
41  
42  public final class CryptoUtil
43  {
44      /** the size of the internal buffer to copy streams */
45      private static final int BUFFER_SIZE = 1024;
46  
47      /**
48       * Copies from a source to a target object using encryption
49       *
50       * @param source the source object
51       * @param target the target object
52       * @param password the password to use for encryption
53       * @throws GeneralSecurityException accessing JCE failed
54       * @throws IOException accessing the souce failed
55       *
56       */
57      public static void encrypt( Object source, Object target, char[] password )
58          throws GeneralSecurityException, IOException
59      {
60          CryptoUtil.encrypt(
61              CryptoUtil.getCryptoStreamFactory(),
62              source,
63              target,
64              password
65              );
66      }
67  
68      /**
69       * Copies from a source to a target object using encryption and a
70       * caller supplied CryptoStreamFactory.
71       *
72       * @param factory the factory to create the crypto streams
73       * @param source the source object
74       * @param target the target object
75       * @param password the password to use for encryption
76       * @throws GeneralSecurityException accessing JCE failed
77       * @throws IOException accessing the souce failed
78       */
79      public static void encrypt(
80          CryptoStreamFactory factory, Object source, Object target, char[] password )
81          throws GeneralSecurityException, IOException
82      {
83          InputStream is = CryptoUtil.createInputStream( source );
84          OutputStream os = CryptoUtil.createOutputStream( target );
85          OutputStream eos = factory.getOutputStream( os, password );
86          CryptoUtil.copy( is, eos );
87      }
88  
89      /**
90       * Copies from a source to a target object using decryption.
91       *
92       * @param source the source object
93       * @param target the target object
94       * @param password the password to use for decryption
95       * @throws GeneralSecurityException accessing JCE failed
96       * @throws IOException accessing the souce failed
97       */
98      public static void decrypt( Object source, Object target, char[] password )
99          throws GeneralSecurityException, IOException
100     {
101         CryptoUtil.decrypt(
102             CryptoUtil.getCryptoStreamFactory(),
103             source,
104             target,
105             password
106             );
107     }
108 
109     /**
110      * Copies from a source to a target object using decryption and a
111      * caller-suppier CryptoStreamFactory.
112      *
113      * @param factory the factory to create the crypto streams
114      * @param source the source object
115      * @param target the target object
116      * @param password the password to use for decryption
117      * @throws GeneralSecurityException accessing JCE failed
118      * @throws IOException accessing the souce failed
119      */
120     public static void decrypt(
121         CryptoStreamFactory factory, Object source, Object target, char[] password )
122         throws GeneralSecurityException, IOException
123     {
124         InputStream is = CryptoUtil.createInputStream( source );
125         OutputStream os = CryptoUtil.createOutputStream( target );
126         InputStream dis = factory.getInputStream( is, password );
127         CryptoUtil.copy( dis, os );
128     }
129 
130     /**
131      * Encrypts a string into a hex string.
132      *
133      * @param plainText the plain text to be encrypted
134      * @param password the password for encryption
135      * @return the encrypted string
136      * @throws GeneralSecurityException accessing JCE failed
137      * @throws IOException accessing the souce failed
138      */
139     public static String encryptString( String plainText, char[] password )
140         throws GeneralSecurityException, IOException
141     {
142         return CryptoUtil.encryptString(
143             CryptoUtil.getCryptoStreamFactory(),
144             plainText,
145             password
146             );
147     }
148 
149     /**
150      * Encrypts a string into a hex string.
151      *
152      * @param factory the factory to create the crypto streams
153      * @param plainText the plain text to be encrypted
154      * @param password the password for encryption
155      * @return the encrypted string
156      * @throws GeneralSecurityException accessing JCE failed
157      * @throws IOException accessing the souce failed
158      */
159     public static String encryptString(
160         CryptoStreamFactory factory, String plainText, char[] password )
161         throws GeneralSecurityException, IOException
162     {
163         ByteArrayOutputStream bais = new ByteArrayOutputStream();
164         CryptoUtil.encrypt( factory, plainText, bais, password );
165         return HexConverter.toString( bais.toByteArray() );
166     }
167 
168     /**
169      * Decrypts an encrypted string into the plain text. The encrypted
170      * string must be a hex string created by encryptString.
171      *
172      * @param cipherText the encrypted text to be decrypted
173      * @param password the password for decryption
174      * @return the decrypted string
175      * @throws GeneralSecurityException accessing JCE failed
176      * @throws IOException accessing the souce failed
177      */
178     public static String decryptString( String cipherText, char[] password )
179         throws GeneralSecurityException, IOException
180     {
181         return CryptoUtil.decryptString(
182             CryptoUtil.getCryptoStreamFactory(),
183             cipherText,
184             password
185             );
186     }
187 
188     /**
189      * Decrypts an encrypted string into the plain text. The encrypted
190      * string must be a hex string created by encryptString.
191      *
192      * @param factory the factory to create the crypto streams
193      * @param cipherText the encrypted text to be decrypted
194      * @param password the password for decryption
195      * @return the decrypted string
196      * @throws GeneralSecurityException accessing JCE failed
197      * @throws IOException accessing the souce failed
198      */
199     public static String decryptString(
200         CryptoStreamFactory factory, String cipherText, char[] password )
201         throws GeneralSecurityException, IOException
202     {
203         byte[] buffer = HexConverter.toBytes( cipherText );
204         ByteArrayOutputStream bais = new ByteArrayOutputStream();
205         CryptoUtil.decrypt( factory, buffer, bais, password );
206         return new String( bais.toByteArray(), "utf-8" );
207     }
208 
209     ///////////////////////////////////////////////////////////////////////////
210     // Private Implementation
211     ///////////////////////////////////////////////////////////////////////////
212 
213     /**
214      * Create an input stream supporting the following types
215      *
216      * <ul>
217      *  <li>String</li>
218      *  <li>File</li>
219      *  <li>byte[]</li>
220      *  <li>char[]</li>
221      *  <li>ByteArrayOutputStream</li>
222      *  <li>InputStream</li>
223      * </ul>
224      *
225      * @param source the source object
226      * @return the created input stream
227      * @throws IOException creating the input stream failed
228      */
229     private static InputStream createInputStream( Object source )
230         throws IOException
231     {
232         InputStream is = null;
233 
234         // create an InputStream
235 
236         if( source instanceof String )
237         {
238             byte[] content = ((String) source).getBytes("utf-8");
239             is = new ByteArrayInputStream( content );
240         }
241         else if( source instanceof File )
242         {
243             is = new FileInputStream( (File) source );
244         }
245         else if( source instanceof byte[] )
246         {
247             is = new ByteArrayInputStream( (byte[]) source );
248         }
249         else if( source instanceof char[] )
250         {
251             byte[] content = new String((char[])source).getBytes("utf-8");
252             is = new ByteArrayInputStream( content );
253         }
254         else if( source instanceof ByteArrayOutputStream )
255         {
256             byte[] content = ((ByteArrayOutputStream) source).toByteArray();
257             is = new ByteArrayInputStream( content );
258         }
259         else
260         {
261             is = (InputStream) source;
262         }
263 
264         return is;
265     }
266 
267     /**
268      * Create an output stream supporting the following types
269      *
270      * <ul>
271      *  <li>File</li>
272      *  <li>OutputStream</li>
273      * </ul>
274      *
275      * @param target the target object
276      * @return the output stream
277      * @throws IOException creating the output stream failed
278      */
279     private static OutputStream createOutputStream( Object target )
280         throws IOException
281     {
282         OutputStream os = null;
283 
284         if( target instanceof File )
285         {
286             os = new FileOutputStream( (File) target );
287         }
288         else
289         {
290             os = (OutputStream) target;
291         }
292 
293         return os;
294     }
295 
296     /**
297      * Pumps the input stream to the output stream.
298      *
299      * @param is the source input stream
300      * @param os the target output stream
301      * @throws IOException the copying failed
302      */
303     public static void copy( InputStream is, OutputStream os )
304         throws IOException
305     {
306         byte[] buf = new byte[BUFFER_SIZE];
307         int n = 0;
308         int total = 0;
309 
310         while ((n = is.read(buf)) > 0)
311         {
312             os.write(buf, 0, n);
313             total += n;
314         }
315 
316         is.close();
317 
318         os.flush();
319         os.close();
320     }
321 
322     /**
323      * @return the CryptoStreamFactory to be used
324      */
325     public static CryptoStreamFactory getCryptoStreamFactory()
326     {
327         return CryptoStreamFactoryImpl.getInstance();
328     }
329 }