title: Access encrypted database from H2 console
body: <p>I want to store my H2 database as an encrypted file and access its web interface.</p>
  
  <p>I configured H2 database so that I can access web interface to manipulate the database under <code>console/db</code> address.</p>
  
  <p>When I do not use encryption everything works fine.</p>
  
  <p>When I add <code>CIPHER=AES</code> to <code>db.url</code> I cannot log into the database and get below exception:</p>
  
  <pre><code>File corrupted while reading record: null. Possible solution: use the recovery tool [90030-191] 90030/90030 (Help)
  org.h2.jdbc.JdbcSQLException: Uszkodzenie pliku podczas wczytywania rekordu: null
  File corrupted while reading record: null. Possible solution: use the recovery tool [90030-191]
      at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
      at org.h2.message.DbException.get(DbException.java:168)
      at org.h2.mvstore.db.MVTableEngine$Store.convertIllegalStateException(MVTableEngine.java:195)
      at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:167)
      at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:99)
      at org.h2.engine.Database.getPageStore(Database.java:2460)
      at org.h2.engine.Database.open(Database.java:692)
      at org.h2.engine.Database.openDatabase(Database.java:270)
      at org.h2.engine.Database.&lt;init&gt;(Database.java:264)
      at org.h2.engine.Engine.openSession(Engine.java:65)
      at org.h2.engine.Engine.openSession(Engine.java:175)
      at org.h2.engine.Engine.createSessionAndValidate(Engine.java:153)
      at org.h2.engine.Engine.createSession(Engine.java:136)
      at org.h2.engine.Engine.createSession(Engine.java:28)
      at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:349)
      at org.h2.jdbc.JdbcConnection.&lt;init&gt;(JdbcConnection.java:107)
      at org.h2.jdbc.JdbcConnection.&lt;init&gt;(JdbcConnection.java:91)
      at org.h2.Driver.connect(Driver.java:72)
      at org.h2.server.web.WebServer.getConnection(WebServer.java:735)
      at org.h2.server.web.WebApp.login(WebApp.java:955)
      at org.h2.server.web.WebApp.process(WebApp.java:211)
      at org.h2.server.web.WebApp.processRequest(WebApp.java:170)
      at org.h2.server.web.WebServlet.doGet(WebServlet.java:125)
      at org.h2.server.web.WebServlet.doPost(WebServlet.java:162)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
      at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: java.lang.IllegalStateException: Store header is corrupt: nio:/home/robak/db/adzfo.mv.db [1.4.191/6]
      at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:773)
      at org.h2.mvstore.MVStore.readStoreHeader(MVStore.java:603)
      at org.h2.mvstore.MVStore.&lt;init&gt;(MVStore.java:353)
      at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2888)
      at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:154)
      ... 47 more
  </code></pre>
  
  <h3>Database Configuration</h3>
  
  <pre><code>db.driver=org.h2.Driver
  db.url=jdbc:h2:file:~/db/app_name;AUTO_SERVER=TRUE;CIPHER=AES
  db.username=user
  db.password=password
  </code></pre>
  
  <h3>Servlet Context</h3>
  
  <pre><code>  private void configureDatabaseConsole(ServletContext servletContext) {
      ServletRegistration.Dynamic h2Servlet = servletContext.addServlet("h2console", WebServlet.class);
      h2Servlet.setLoadOnStartup(2);
      h2Servlet.addMapping("/console/db/*");
    }
  </code></pre>
  
  <h3>Data source</h3>
  
  <pre><code>  @Bean
    public DataSource dataSource() {
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      dataSource.setDriverClassName(getProperty(DRIVER));
      dataSource.setUrl(getProperty(URL));
      dataSource.setUsername(getProperty(USERNAME));
      dataSource.setPassword(FILE_PASSWORD + " " + getProperty(PASSWORD));
      return dataSource;
    }
  </code></pre>
  
  <p>What should I do to have an encrypted database as a file on a hard drive and to access its console via web interface?</p>