1
2
3
4
5
6
7
8
9
10 package org.wiztools.wizcrypt;
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.io.OutputStream;
15 import java.nio.charset.Charset;
16 import java.util.Arrays;
17 import java.util.ResourceBundle;
18 import java.util.zip.GZIPInputStream;
19 import java.util.zip.GZIPOutputStream;
20 import javax.crypto.CipherInputStream;
21 import javax.crypto.CipherOutputStream;
22
23 /***
24 * This class has the public APIs of WizCrypt application to do encryption and decryption.
25 * @see CipherKeyGen
26 * @see CipherKey
27 * @author subhash
28 */
29 public final class WizCrypt {
30
31 private static final ResourceBundle rb = ResourceBundle.getBundle("org.wiztools.wizcrypt.wizcryptmsg");
32
33 /*** Disallow public creation of instances of this object. */
34 private WizCrypt() {
35 }
36
37 /***
38 * This is the public API exposed to encrypt.
39 *
40 *
41 * @param is The input stream that needs to be encrypted.
42 * @param os The output stream where the encrypted content
43 * of <code>is</code> need to be written.
44 * @param ck The <code>CipherKey</code> object. This has to be
45 * created by passing the password to
46 * <code>CipherKeyGen.getCipherKeyForEncrypt(String keyStr)</code>.
47 * @param cb <code>Callback</code> object for monitoring the progress.
48 * @param size The size of the <code>is</code> stream. When this is passed,
49 * the <code>Callback.notifyProgress(long value)</code> will receive
50 * the percentage completed. If this is not passed, it will get the
51 * number of bytes read and processed.
52 * @see CipherKeyGen#getCipherKeyForEncrypt(String keyStr)
53 * @see CipherKey
54 * @see Callback
55 * @throws IOException <code>IOException</code> is thrown when
56 * faced with IO issues during read/write.
57 */
58 public static void encrypt(final InputStream is, final OutputStream os,
59 final CipherKey ck, final Callback cb, final long size) throws IOException{
60
61 CipherInputStream cis = null;
62 OutputStream gos = new GZIPOutputStream(os);
63 try{
64 if(cb != null){
65 cb.begin();
66 }
67
68 cis = new CipherInputStream(is, ck.cipher);
69
70
71 byte[] versionStr = FileFormatVersion.WC07.getBytes(WizCryptAlgorithms.STR_ENCODE);
72 gos.write(versionStr);
73
74
75 gos.write(ck.passKeyHash);
76
77 int i = -1;
78 byte[] buffer = new byte[0xFFFF];
79 long readSize = 0;
80 while((i=cis.read(buffer)) != -1){
81 gos.write(buffer, 0, i);
82 readSize += i;
83 if(cb != null){
84 if(size == -1){
85 cb.notifyProgress(readSize);
86 }
87 else{
88 cb.notifyProgress(readSize * 100 / size);
89 }
90 }
91 }
92 }
93 finally{
94 try{
95 if(gos != null){
96 gos.close();
97 }
98 } catch(IOException ioe){
99 System.err.println(ioe.getMessage());
100 }
101 try{
102 if(cis != null){
103 cis.close();
104 }
105 } catch(IOException ioe){
106 System.err.println(ioe.getMessage());
107 }
108 if(cb != null){
109 cb.end();
110 }
111 }
112 }
113
114 /***
115 * @see #encrypt(InputStream is, OutputStream os,
116 * CipherKey ck, Callback cb, long size)
117 */
118 public static void encrypt(final InputStream is, final OutputStream os,
119 final CipherKey ck) throws IOException{
120 encrypt(is, os, ck, null, -1);
121 }
122
123 /***
124 * @see #encrypt(InputStream is, OutputStream os,
125 * CipherKey ck, Callback cb, long size)
126 */
127 public static void encrypt(final InputStream is, final OutputStream os,
128 final CipherKey ck, final Callback cb) throws IOException{
129 encrypt(is, os, ck, cb, -1);
130 }
131
132 /***
133 * This is the public API exposed to decrypt.
134 *
135 *
136 * @param is The input stream that needs to be decrypted.
137 * @param os The output stream where the decrypted content
138 * of <code>is</code> need to be written.
139 * @param ck The <code>CipherKey</code> object. This has to be
140 * created by passing the password to
141 * <code>CipherKeyGen.getCipherKeyForDecrypt(String keyStr)</code>.
142 * @param cb <code>Callback</code> object for monitoring the progress.
143 * @param size The size of the <code>is</code> stream. When this is passed,
144 * the <code>Callback.notifyProgress(long value)</code> will receive
145 * the percentage completed. If this is not passed, it will get the
146 * number of bytes read and processed.
147 * @see CipherKeyGen#getCipherKeyForDecrypt(String keyStr)
148 * @see CipherKey
149 * @see Callback
150 * @throws PasswordMismatchException <code>PasswordMismatchException</code>
151 * is thrown when the supplied password is wrong.
152 * @throws IOException <code>IOException</code> is thrown when faced with
153 * IO issues during read/write.
154 */
155 public static void decrypt(final InputStream is, final OutputStream os,
156 final CipherKey ck, final Callback cb, final long size) throws IOException, PasswordMismatchException{
157
158 CipherOutputStream cos = null;
159 InputStream gis = new GZIPInputStream(is);
160 try{
161 if(cb != null){
162 cb.begin();
163 }
164
165
166 byte[] versionStr = FileFormatVersion.WC07.getBytes(WizCryptAlgorithms.STR_ENCODE);
167 int versionByteLen = versionStr.length;
168 byte[] magicNumber = new byte[versionByteLen];
169 gis.read(magicNumber, 0, versionByteLen);
170 System.out.println("magicNumber: "+new String(magicNumber));
171
172
173 byte[] filePassKeyHash = new byte[16];
174 gis.read(filePassKeyHash, 0, 16);
175
176 if(!Arrays.equals(ck.passKeyHash, filePassKeyHash)){
177 throw new PasswordMismatchException(rb.getString("err.pwd.not.match"));
178 }
179
180 cos = new CipherOutputStream(os, ck.cipher);
181
182 int i = -1;
183 byte[] buffer = new byte[0xFFFF];
184 long readSize = 0;
185 while((i=gis.read(buffer)) != -1){
186 cos.write(buffer, 0, i);
187 readSize += i;
188 if(cb != null){
189 if(size == -1){
190 cb.notifyProgress(readSize);
191 }
192 else{
193 cb.notifyProgress(readSize * 100 / size);
194 }
195 }
196 }
197 }
198 finally{
199 try{
200 if(cos != null){
201 cos.close();
202 }
203 } catch(IOException ioe){
204 System.err.println(ioe.getMessage());
205 }
206 try{
207 if(gis != null){
208 gis.close();
209 }
210 } catch(IOException ioe){
211 System.err.println(ioe.getMessage());
212 }
213 if(cb != null){
214 cb.end();
215 }
216 }
217 }
218
219 /***
220 * @see #decrypt(InputStream is, OutputStream os,
221 * CipherKey ck, Callback cb, long size)
222 */
223 public static void decrypt(final InputStream is, final OutputStream os,
224 final CipherKey ck) throws IOException, PasswordMismatchException{
225 decrypt(is, os, ck, null, -1);
226 }
227
228 /***
229 * @see #decrypt(InputStream is, OutputStream os,
230 * CipherKey ck, Callback cb, long size)
231 */
232 public static void decrypt(final InputStream is, final OutputStream os,
233 final CipherKey ck, final Callback cb) throws IOException,
234 PasswordMismatchException{
235 decrypt(is, os, ck, cb, -1);
236 }
237 }