KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > io > crypt > XTeaEncryptionFileAdapter


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.io.crypt;
22
23 import java.io.*;
24
25 import com.db4o.io.*;
26
27 /**
28 * XTeaEncryptionFileAdapter is an encryption IoAdapter plugin for db4o file IO
29 * <br>
30 * that realized XTEA encryption algorithm. <br>
31 * <br>
32 * Configure db4o to add this encryption mechanism:<br>
33 * <code>Db4o.configure().io(new XTeaEncryptionFileAdapter("password"));
34 * </code><br>
35 * Any changes must be taken with the same password.<br>
36 * <br>
37 *
38 *
39 * Remember that any configuration settings must be set before opening
40 * ObjectContainer.
41 */

42 public class XTeaEncryptionFileAdapter extends IoAdapter {
43     // used as prototype in factory mode and as delegate in implementation mode
44
private IoAdapter _adapter;
45
46     // factory mode member
47
private String JavaDoc _key;
48
49     // implementation mode members
50
private XTEA _xtea;
51
52     private long _pos;
53
54     private XTEA.IterationSpec _iterat;
55
56     private static final boolean DEBUG = false;
57
58     /**
59      *
60      * creates a new XTeaEncryptionFileAdapter instance using the given String as
61      * password. The default value of rounds is 32;
62      *
63      * @param password
64      * the key, used in ecryption/decryption routine.
65      */

66     public XTeaEncryptionFileAdapter(String JavaDoc password) {
67         this(new RandomAccessFileAdapter(), password, XTEA.ITERATIONS32);
68
69     }
70
71     /**
72      *
73      * Creates a new XTeaEncryptionFileAdapter instance using the given String
74      * as password and iterations count.
75      *
76      * @param password
77      * the key, used in ecryption/decryption routine.
78      * @param iterat
79      * iterations count. Possible values are 8, 16, 32 and 64.
80      *
81      */

82     public XTeaEncryptionFileAdapter(String JavaDoc password, XTEA.IterationSpec iterat) {
83         this(new RandomAccessFileAdapter(), password, iterat);
84
85     }
86
87     /**
88      *
89      * Creates a new XTeaEncryptionFileAdapter instance using delegated
90      * IoAdapter, the given password and iterations count.
91      *
92      * @param adapter
93      * delegated IoAdapter,
94      * @param password
95      * the key, used in ecryption/decryption routine.
96      * @param iterat
97      * iterations count. Possible values are 8, 16, 32 and 64.
98      */

99     public XTeaEncryptionFileAdapter(IoAdapter adapter, String JavaDoc password,
100             XTEA.IterationSpec iterat) {
101         _adapter = adapter;
102         _key = password;
103         _iterat = iterat;
104     }
105     /**
106      *
107      * Creates a new XTeaEncryptionFileAdapter instance using delegated
108      * IoAdapter and the given password. The default value of rounds is 32.
109      *
110      * @param adapter
111      * delegated IoAdapter,
112      * @param password
113      * the key, used in ecryption/decryption routine.
114      *
115      */

116     public XTeaEncryptionFileAdapter(IoAdapter adapter, String JavaDoc password) {
117         _adapter = adapter;
118         _key = password;
119         _iterat = XTEA.ITERATIONS32;
120     }
121
122     private XTeaEncryptionFileAdapter(IoAdapter adapter, XTEA xtea) {
123         _adapter = adapter;
124         _xtea = xtea;
125     }
126
127     /**
128      * implement to close the adapter
129      */

130     public void close() throws IOException {
131         _adapter.close();
132     }
133
134     public void delete(String JavaDoc path) {
135         _adapter.delete(path);
136     }
137     
138     public boolean exists(String JavaDoc path) {
139         return _adapter.exists(path);
140     }
141     
142     /**
143      * implement to return the absolute length of the file
144      */

145     public long getLength() throws IOException {
146         return _adapter.getLength();
147     }
148
149     /**
150      * implement to open the file
151      */

152     public IoAdapter open(String JavaDoc path, boolean lockFile, long initialLength)
153             throws IOException {
154         //System.out.println(_iterat + " iteration number");
155
return new XTeaEncryptionFileAdapter(_adapter.open(path, lockFile,
156                 initialLength), new XTEA(_key, _iterat));
157
158     }
159
160     /**
161      * implement to read and decrypt a buffer
162      */

163     public int read(byte[] bytes, int length) throws IOException {
164         long origPos = _pos;
165         int fullLength = length;
166         int prePad = (int) (_pos % 8);
167         fullLength += prePad;
168         int overhang = fullLength % 8;
169         int postPad = (overhang == 0 ? 0 : 8 - (overhang));
170         fullLength += postPad;
171         byte[] pb = new byte[fullLength];
172         if (prePad != 0) {
173             seek(_pos - prePad);
174         }
175         int readResult = _adapter.read(pb);
176         if (DEBUG) {
177             log("3. before dencrypt/read->", pb);
178         }
179         _xtea.decrypt(pb);
180
181         System.arraycopy(pb, prePad, bytes, 0, length);
182         if (DEBUG) {
183             log("4. after dencrypt/read->", pb);
184         }
185         seek(origPos + length);
186         return length;
187     }
188
189     /**
190      * implement to set the read/write pointer in the file
191      */

192     public void seek(long pos) throws IOException {
193         _pos = pos;
194         _adapter.seek(pos);
195     }
196
197     /**
198      * implement to flush the file contents to storage
199      */

200     public void sync() throws IOException {
201         _adapter.sync();
202     }
203
204     /**
205      * implement to write and encrypt a buffer
206      */

207     public void write(byte[] buffer, int length) throws IOException {
208         long origPos = _pos;
209         int fullLength = length;
210         int prePad = (int) (_pos % 8);
211         fullLength += prePad;
212         int overhang = fullLength % 8;
213         int postPad = (overhang == 0 ? 0 : 8 - (overhang));
214         fullLength += postPad;
215         byte[] pb = new byte[fullLength];
216         if (prePad != 0) {
217             seek(origPos - prePad);
218         }
219         // NOTE: This heuristic may break if unaligned accesses within db4o (for example
220
// due to config block layout changes) change behavior. To make this more safe
221
// (but at the cost of a ~20% performance penalty on writes) make this read/seek
222
// action unconditional, i.e. comment the if block.
223
if (blockSize() % 8 != 0 || prePad != 0) {
224             read(pb);
225             seek(origPos - prePad);
226         }
227         System.arraycopy(buffer, 0, pb, prePad, length);
228         if (prePad == 0) {
229             // for (int i = buffer.length; i < pb.length; i++) {
230
// pb[i] = (byte) (Math.random());
231
// }
232
}
233         if (DEBUG) {
234             log("1. before encrypt/write->", pb);
235         }
236
237         _xtea.encrypt(pb);
238         if (DEBUG) {
239             log("2. after encrypt/write->", pb);
240         }
241         _adapter.write(pb, pb.length);
242         seek(origPos + length);
243     }
244
245     private void log(String JavaDoc msg, byte[] buf) {
246         System.out.println("\n " + msg);
247         for (int idx = 0; idx < buf.length; idx++) {
248             System.out.print(buf[idx] + " ");
249         }
250     }
251
252 }
253
Popular Tags