1 package org.apache.fulcrum.jce.crypto;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
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 }