使用ChangeFileEncryption()解密H2数据库失败

时间:2016-11-29 12:37:15

标签: java encryption h2 recovery

我想解密加密的H2数据库,以便能够在以下步骤中使用恢复工具。通过“ChangeFileEncryption”解密似乎无法正常工作。一个小样本程序:

public class H2DecryptionTest{
    public static void main(String[] args){
      try {
          String path = "C:\\test";
          String dbName = "database";
          String dbPassword = "password";
          String userName = "username";
          String userPassword = "userpassword";
          JdbcDataSource datasource = new JdbcDataSource();
          String dbAttributes = "\\"+dbName+";USER="+userName+";PASSWORD="+userPassword+" " + dbPassword;
          datasource.setURL("jdbc:h2:" + path + dbAttributes);
          datasource.setUser(userName);
          datasource.setPassword(userPassword);

          Connection connection = datasource.getConnection();

          insertDefaultValues(connection);
          connection.close();

          /////// the following does not work properly: //////////
          ChangeFileEncryption.execute(path, dbName, "AES", dbPassword.toCharArray(), null, false);

          Recover.execute(path, dbName); // <<<<---- Exception is thrown here!
      } catch (Exception e) {
        e.printStackTrace();
      }
  }

  // just writing some stuff into the database to see that creation was ok, not important
  private static void insertDefaultValues(Connection connection) throws SQLException {
      Statement stmt = null;
      try {
          connection.setAutoCommit(false);
          stmt = connection.createStatement();
          stmt.execute("CREATE TABLE PERSON(id int primary key, name varchar(255))");
          stmt.execute("INSERT INTO PERSON(id, name) VALUES(1, 'One')");
          stmt.execute("INSERT INTO PERSON(id, name) VALUES(2, 'Two')");
          stmt.execute("INSERT INTO PERSON(id, name) VALUES(3, 'Three')");

          ResultSet rs = stmt.executeQuery("select * from PERSON");
          System.out.println("H2 Database inserted through Statement");
          while (rs.next()) {
              System.out.println("Id "+rs.getInt("id")+" Name "+rs.getString("name"));
          }
          stmt.close();
          connection.commit();
      } catch (SQLException e) {
          System.out.println("Exception Message " + e.getLocalizedMessage());
      } catch (Exception e) {
          e.printStackTrace();
      }
    }
}

控制台输出是:

    Connected to the target VM, address: '127.0.0.1:63156', transport: 'socket'
    H2 Database inserted through Statement
    Id 1 Name One
    Id 2 Name Two
    Id 3 Name Three
    Disconnected from the target VM, address: '127.0.0.1:63156', transport: 'socket'
    java.lang.IllegalStateException: Store header is corrupt: nio:C:/test/database.mv.db [1.4.193/6]
        at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:765)
        at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:609)
        at org.h2.mvstore.MVStore.<init>(MVStore.java:359)
        at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2923)
        at org.h2.mvstore.MVStoreTool.info(MVStoreTool.java:346)
        at org.h2.tools.Recover.process(Recover.java:342)
        at org.h2.tools.Recover.execute(Recover.java:320)
        at H2DecryptionTest.main(H2DecryptionTest.java:22)

    Process finished with exit code 0

所以我的问题是:如何正确解密数据库?在此先感谢:)

1 个答案:

答案 0 :(得分:0)

我自己发现了错误 - 也许它可以帮助别人:

  • 在示例中,我忘记在dbAttributes中添加加密方法(cypher = AES)。

    String dbAttributes = "\\"+dbName+";CIPHER=AES;USER="+userName+";PASSWORD="+userPassword+" " + dbPassword;
    
  • 我为ChangeFileEncryption使用了错误的密码。第一个密码(在这种情况下是“userPassword”)应该这样做。