Hi Andrew,
The reason why encryption and replication is not documented is because
it has not been tested at all. Theoretically, there is nothing I can
think of that will prevent it from working [1]. On the other hand, we
may have forgotten some details that I expect to be easy fixes if
somebody volunteers.
The hang you get on the slave is expected. When you boot a database in
slave mode, the connection attempt is designed to hang until the master
connects to it. For details, take a look at this page in the Derby
Server and Admin guide:
http://db.apache.org/derby/docs/10.4/adminguide/cadminreplication.html
I have created an encrypted database and tried the connection string you
suggested [2]. I successfully set up replication, and did some simple
DML and DDL operations on the master. The operations were correctly
reflected on the slave after failover, as expected.
Thus:
* It does work in theory
* A simple test confirmed that it works
* This combination of features has not been tested thoroughly.
* We may have forgotten some corner cases that needs to be fixed
Conclusion:
* I can not guarantee correct results, although I am pretty sure it will
work.
[1] Replication works by sending the (recovery) log records from the
master to the slave. The log records store physical changes to disk
blocks, and in encrypted mode these changes are encrypted as well.
Replication has a lot in common with Derby's Online Backup feature which
*does* support encryption.
[2]
1. Master: connect
'jdbc:derby:enctest2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=test;create=true';
2. Master: CALL SYSCS_UTIL.SYSCS_FREEZE_DATABASE();
3. Slave: connect
'jdbc:derby:enctest2;startSlave=true;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=test';
4. Master: connect
'jdbc:derby:enctest2;startMaster=true;slaveHost=localhost;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=test';
5. Master: do some test DDL and DML operations
6: Master: connect 'jdbc:derby:enctest2;failover=true';
7: Slave: connect
'jdbc:derby:enctest2;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=test';
8. Slave: ensure results are as expected
Hope this helps,
Jørgen Løland
Andrew Lawrenson wrote:
Hi All,
is it possible to use replication to replicate an encrypted database.
Various things hint that it isn't supported (such as the StartSlave attribute
not specifying that you can combine it with encryptionKey), but I can't find
anything explicitly saying it isn't supported.
If I boot the slave database without the encryption key, I get an exception with
SQLState XBM06, as expected. If I pass in the encryption details as well, so my
connection attributes contains the following:
"startSlave=true;slaveHost=192.168.0.211;slavePort=6959;encryptionAlgorithm=DES/CBC/NoPadding;encryptionKey=aaaaaaaabbbbbbbb"
then derby hangs indefinately whilst booting:
java.lang.Thread.sleep(Native Method)
org.apache.derby.impl.db.SlaveDatabase.verifySuccessfulBoot(Unknown Source)
org.apache.derby.impl.db.SlaveDatabase.boot(Unknown Source)
org.apache.derby.impl.services.monitor.BaseMonitor.boot(Unknown Source)
org.apache.derby.impl.services.monitor.TopService.bootModule(Unknown Source)
org.apache.derby.impl.services.monitor.BaseMonitor.bootService(Unknown
Source)
org.apache.derby.impl.services.monitor.BaseMonitor.startProviderService(Unknown
Source)
org.apache.derby.impl.services.monitor.BaseMonitor.findProviderAndStartService(Unknown
Source)
org.apache.derby.impl.services.monitor.BaseMonitor.startPersistentService(Unknown
Source)
org.apache.derby.iapi.services.monitor.Monitor.startPersistentService(Unknown
Source)
org.apache.derby.impl.jdbc.EmbedConnection.bootDatabase(Unknown Source)
org.apache.derby.impl.jdbc.EmbedConnection.<init>(Unknown Source)
org.apache.derby.impl.jdbc.EmbedConnection30.<init>(Unknown Source)
org.apache.derby.impl.jdbc.EmbedConnection40.<init>(Unknown Source)
org.apache.derby.jdbc.Driver40.getNewEmbedConnection(Unknown Source)
org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
org.apache.derby.jdbc.AutoloadedDriver.connect(Unknown Source)
java.sql.DriverManager.getConnection(DriverManager.java:582)
java.sql.DriverManager.getConnection(DriverManager.java:185)
Is it possible for anyone to confirm if this should be supported or not?
many thanks,
Andrew Lawrenson