在Android上使用SQLCipher

Ari*_*Roy 0 encryption android sqlcipher android-sqlite

我之前已经问过这个问题并且没有得到任何适当的答案.

我在Play商店发布了一个应用程序,它大量使用SQLite数据库.

现在我需要使用SQLCipher来保护数据库.这是我面临的一些问题.

1)如何将SQLCipher与我现有的未加密数据库无缝集成,以便我的应用程序正常工作但现在数据库已加密?

(我想要一个简短的教程)

2)我应该如何检查数据库是否未加密,然后如何加密?我应该只做一次吗?什么应该是最好的做法?

(可能的副本不回答这个)

3)当我加密现有的未加密数据库时,SQLCipher是否创建了一个新数据库?如果是的话,我应该如何管理这个新的?那个未加密的旧数据库怎么样?它还留在那里吗?

(重复问题中也没有提供此解释)

Com*_*are 7

如何将SQLCipher与我现有的未加密数据库无缝集成,以便我的应用程序正常工作但现在数据库已加密?

你没有.除此之外,您必须调整UI以询问用户密码,并确保您可以根据需要请求密码短语(例如,用户从某些"内部"活动中恢复任务,而不仅仅是在用户运行您的密码时应用程序通过启动器图标).

我想要一个简短的教程

首先,这不是Stack Overflow的工作原理.

其次,适用于Android的SQLCipher的合理覆盖范围远远超过单个Stack Overflow答案.例如,我在本书中有一个18页的章节.这个答案已经比绝大多数Android问题都要长了,我不会因为过于宽泛而将这个问题归咎于人们.

我应该如何检查数据库是否未加密

尝试使用SQLCipher for Android类打开它""作为密码.如果成功打开,则数据库未加密.如果失败,无论数据库是否已损坏或加密,并且没有正确的密码,您都无法区分.

我该怎么加密呢?

基本方法是:

  • 打开未加密的数据库

  • 使用ATTACHSQL语句附加空文件以用作新的加密数据库,提供所需的密码,并encrypted在数据库会话中命名附加的数据库

  • 运行SELECT sqlcipher_export('encrypted')打开(未加密)数据库,该数据库将未加密数据库中的数据导出到加密数据库中(数据库模式版本除外,后续步骤处理)

  • 调用getVersion()open(未加密)数据库并保持该值一点

  • 关闭未加密的数据库

  • 使用密码打开加密数据库

  • 调用setVersion()加密数据库,提供从未getVersion()加密数据库缓存的值

  • 关闭加密的数据库

  • 如果需要,删除未加密的数据库并将加密的数据库重命名为现在删除的未加密数据库的名称,以便您的转换似乎就位

该实用方法实现了上述方法:

  public static void encrypt(Context ctxt, String dbName,
                             String passphrase) throws IOException {
    File originalFile=ctxt.getDatabasePath(dbName);

    if (originalFile.exists()) {
      File newFile=
          File.createTempFile("sqlcipherutils", "tmp",
                              ctxt.getCacheDir());
      SQLiteDatabase db=
          SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),
                                      "", null,
                                      SQLiteDatabase.OPEN_READWRITE);

      db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
                                  newFile.getAbsolutePath(), passphrase));
      db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
      db.rawExecSQL("DETACH DATABASE encrypted;");

      int version=db.getVersion();

      db.close();

      db=
          SQLiteDatabase.openDatabase(newFile.getAbsolutePath(),
                                      passphrase, null,
                                      SQLiteDatabase.OPEN_READWRITE);
      db.setVersion(version);
      db.close();

      originalFile.delete();
      newFile.renameTo(originalFile);
    }
  }
Run Code Online (Sandbox Code Playgroud)

为了充分披露,我暂时没有尝试过,所以可能需要进行一些调整.

我应该只做一次吗?

只有你可以回答这个问题,因为这里没有人会对你的应用了解太多.

当我加密现有的未加密数据库时,SQLCipher是否创建了一个新数据库?

是.

如果是的话,我应该如何管理这个新的?

只有你可以回答这个问题,因为这里没有人会对你的应用了解太多.

那个未加密的旧数据库怎么样?它还留在那里吗?

是的,虽然欢迎您在完成后删除它.