在Android中使用SQLCipher

在Android中使用SQLCipher,android,encryption,android-sqlite,sqlcipher,Android,Encryption,Android Sqlite,Sqlcipher,我以前曾问过这个问题,但没有得到任何适当的答案 我在Play Store中发布了一个应用程序,它大量使用SQLite数据库 现在我需要使用SQLCipher保护数据库。以下是我面临的一些问题 1) 如何将SQLCipher与我现有的未加密数据库无缝集成,使我的应用程序正常工作,但现在数据库已加密 (我想要一个关于这个的简短教程) 2) 如何检查数据库是否未加密,然后如何加密?我应该只做一次吗?最佳实践应该是什么 (可能的副本无法回答此问题) 3) 当我加密现有的未加密数据库时,SQLCipher

我以前曾问过这个问题,但没有得到任何适当的答案

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

现在我需要使用SQLCipher保护数据库。以下是我面临的一些问题

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

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

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

(可能的副本无法回答此问题)

3) 当我加密现有的未加密数据库时,SQLCipher是否创建新数据库?如果是,我应该如何管理这个新项目?那我的旧数据库呢,它是未加密的?它还在那里吗

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

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

你没有。除其他事项外,您必须调整UI以向用户请求密码短语,并确保您可以根据需要请求该密码短语(例如,用户从某些“内部”活动恢复任务,而不仅仅是当用户通过启动器图标运行您的应用程序时)

我想要一个关于这个的简短教程

首先,堆栈溢出不是这样工作的

其次,SQLCipher for Android的覆盖率远远超过了单堆栈溢出答案的覆盖率。例如,我有。这个答案已经比绝大多数安卓系统的问题都要长,我不会因为这个问题过于宽泛而责怪人们

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

尝试使用SQLCipher for Android类打开它,密码短语为“
。如果成功打开,则数据库未加密。如果失败,则表明数据库已损坏或已加密,如果没有正确的密码短语,则无法区分两者之间的区别

我如何加密它

基本方法是:

  • 打开未加密的数据库

  • 使用
    ATTACH
    SQL语句附加一个空文件作为新的加密数据库,提供所需的密码短语,并在数据库会话中将附加的数据库命名为
    encrypted

  • 在开放(未加密)数据库中运行
    SELECT sqlcipher\u export('encrypted')
    ,将数据从未加密数据库导出到加密数据库(数据库架构版本除外,该版本将在后面的步骤中处理)

  • 在打开的(未加密的)数据库上调用
    getVersion()
    ,并保持该值一段时间

  • 关闭未加密的数据库

  • 使用您的密码短语打开加密的数据库

  • 在加密数据库上调用
    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);
    }
  }
为了充分披露,我已经有一段时间没有尝试过了,因此可能需要一些调整

我应该只做一次吗

只有你才能回答这个问题,因为这里没有人会对你的应用程序了解很多

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

如果是,我应该如何管理这个新项目

只有你才能回答这个问题,因为这里没有人会对你的应用程序了解很多

那我的旧数据库呢,它是未加密的?它还在那里吗


是的,但是如果你完成了,欢迎你删除它。

你可以(很快)在你的另一个问题中添加悬赏。不允许再问“同样”的问题。@ArtjomB。这个问题在许多方面与可能的重复问题不同。这个问题更详细,涵盖了广泛的场景。在这种情况下,它太广泛了。每个帖子坚持一个问题,而不是8个(原文如此!)。