I didn't read any earlier posts on the encryption question, but assuming that you find it sufficent for the database file to be encrypted, then the simplest solution is to encrypt the entire script file when it is written to disk.
This should be easy to implement, by writing new ScriptReader/Writer classes wrapping the i/o into a cipher class. I enclose a "proof of concept" sample code here which encrypts using DES, with a fixed Key. I tested it with 1.7.2 RC2. Obviously some design is still required to make the encryption type and key variable.
ScriptWriterEncrypted.java
package org.hsqldb.scriptio;
import java.io.FileOutputStream; import java.io.IOException; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*;
import org.hsqldb.Database; import org.hsqldb.HsqlException; import org.hsqldb.Trace;
/** * * @author Brendan Ryan * @since 1.7.2 * @version 1.7.2 */ class ScriptWriterEncrypted extends ScriptWriterText {
ScriptWriterEncrypted(Database db, String file, boolean includeCached, boolean newFile) throws HsqlException { super(db, file, includeCached, newFile); }
/** * Override the underlying open method to wrap the OutputStream */ protected void openFile() throws HsqlException {
try { Cipher c = Cipher.getInstance("DES"); Key k = new SecretKeySpec("secretpw".getBytes(), "DES"); c.init(Cipher.ENCRYPT_MODE, k);
FileOutputStream fos = new FileOutputStream(outFile, true); fileStreamOut = new CipherOutputStream(fos,c); outDescriptor = fos.getFD(); } catch (IOException e) { throw Trace.error(Trace.FILE_IO_ERROR, outFile); } catch(java.security.NoSuchAlgorithmException exception) { throw Trace.error(Trace.FILE_IO_ERROR, outFile); } catch(java.security.InvalidKeyException exception) { throw Trace.error(Trace.FILE_IO_ERROR, outFile); } catch(javax.crypto.NoSuchPaddingException exception) { throw Trace.error(Trace.FILE_IO_ERROR, outFile); } } }
A matching ScriptReaderEncrypted is equally easy.
package org.hsqldb.scriptio;
import java.io.DataInputStream; import java.io.FileInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*;
import org.hsqldb.Database; import org.hsqldb.HsqlException;
/** * * @author Brendan Ryan * @since 1.7.2 * @version 1.7.2 */ class ScriptReaderEncrypted extends ScriptReaderText {
ScriptReaderEncrypted(Database db, String file) throws HsqlException, IOException { super(db, file); }
protected void openFile() throws IOException {
try { Cipher c = Cipher.getInstance("DES"); Key k = new SecretKeySpec("secretpw".getBytes(), "DES"); c.init(Cipher.DECRYPT_MODE, k);
dataStreamIn = db.isFilesInJar()
? new DataInputStream(new CipherInputStream(getClass().getResourceAsStream(fileName),c))
: new DataInputStream(new CipherInputStream(new FileInputStream(fileName),c));
} catch(java.security.NoSuchAlgorithmException exception) { throw new IOException("NoSuchAlgorithmException"); } catch(java.security.InvalidKeyException exception) { throw new IOException("InvalidKeyException"); } catch(javax.crypto.NoSuchPaddingException exception) { throw new IOException("NoSuchPaddingException"); }
d = new BufferedReader(new InputStreamReader(dataStreamIn)); } }
Then all you need is a simple change in the newScriptWriter method of ScriptWriterBase (and the corresponding newScriptReader in ScriptReaderBase):
public static String[] LIST_SCRIPT_FORMATS = new String[] {
Token.T_TEXT, Token.T_BINARY, null, Token.T_COMPRESSED, Token.T_ENCRYPTED
};
...
public final static int SCRIPT_ENCRYPTED_BINARY_172 = 4;
...
} else if (scriptType == SCRIPT_ENCRYPTED_BINARY_172) {
return new ScriptWriterEncrypted(db, file, includeCachedData,
newFile);
...
All that remains is to define the T_ENCRYPTED constant in Token.java
public static final String T_ENCRYPTED = "ENCRYPTED";
and finally allow the value '4' in the script format command in DatabaseCommandInterpreter.java (case Token.SCRIPTFORMAT):
if (i == 0 || i == 1 || i == 3 || i == 4) { /* <== 4 added */
database.logger.setScriptType(i);
} else {
throw Trace.error(Trace.UNEXPECTED_TOKEN, token);
}
Use the SQL command SET SCRIPTFORMAT ENCRYPTED to change an existing database to encrypted mode. Use the command SET SCRIPTFORMAT TEXT to return to clear text.
Regards Brendan Ryan
Message: 1 Date: Wed, 03 Mar 2004 18:17:10 -0500 From: "Edwin S. Ramirez" <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] Subject: [Hsqldb-developers] Data Encryption Support & Questions
Hello,
I have recently started looking at HSQLDB and I am interested in participating
in it's development. I have added encryption support to the text tables. It currently, encrypts/decrypts each line (record) as it is read/written to the file.
I don't know if the way that I implemented this is the best way, but basically:
TextDatabaseRowInput: public void setSource(String text, int pos) { String temp = cr.decrypt(text) + "\n"; this.text = temp.substring(0, temp.indexOf('\n')); ...
TextDatabaseRowOutput: public byte[] toByteArray() throws IOException { ... return (cr.encrypt(ret)); }
where cr is an object which contains the appropriate key/cipher algorithm for this table.
------------------------------------------------------- This SF.Net email is sponsored by: IBM Linux Tutorials Free Linux tutorial presented by Daniel Robbins, President and CEO of GenToo technologies. Learn everything from fundamentals to system administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click _______________________________________________ hsqldb-developers mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/hsqldb-developers