使用SQLCipher与Android [英] Using SQLCipher with Android

查看:186
本文介绍了使用SQLCipher与Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前已经提过这个问题,没有任何适当的答案。



我在Play商店发布了一个大量使用SQLite数据库的应用程序。 / p>

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



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



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



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



(可能的重复不会回答这个)



3)当我加密我现有的未加密数据库,做SQLCipher创建一个新的数据库?如果是,我应该如何管理这个新的?而我的旧数据库是不加密的呢?还是留在那里?



(这个解释也没有在重复的问题中提供)

解决方案


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


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


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


首先,这不是堆栈溢出的工作原理。



其次,适用于Android的SQLCipher的覆盖范围 em>超过可以适应单个Stack Overflow答案。例如,我在关于该主题的18页的章节。这个答案已经比绝大多数的Android问题更长了,我不会责怪人们把这个问题解决得太广泛了。


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


尝试使用SQLCipher for Android类使用 作为密码。如果它成功打开,则数据库是未加密的。如果失败,数据库已损坏或加密,并且没有适当的密码,您将无法区分差异。


我如何加密它的基本方法是:



$ b

li>

打开未加密的数据库


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


  • 在打开的(未加密的)数据库中运行 SELECT sqlcipher_export('encrypted'),这将将数据从未加密的数据库导出到加密数据库数据库模式版本的异常,以后的步骤处理)


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


  • 关闭未加密pted数据库


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


  • 致电 setVersion()在加密数据库中提供您从未加密数据库的 getVersion()缓存的值


  • 关闭加密的数据库


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




  • 此实用程序方法实现上述方法:

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

    if(originalFile.exists()){
    文件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创建一个新的数据库?


    是的。 >


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


    只有你可以回答这一点,因为这里没人会对你的应用程序有所了解。


    我的旧数据库这是不加密的?是否仍然在那里?


    是的,虽然欢迎您删除它,如果您完成它。 >

    I have previously asked this question and have not got any appropriate answer.

    I have an app published in the Play Store which makes heavy use of SQLite database.

    Now I need to secure the database using SQLCipher. Here are some problems I am facing.

    1) How can I seamlessly integrate SQLCipher with my existing unencrypted database, so that my app works as it works normally but now the databases are encrypted?

    (I would like a short tutorial on this)

    2) How should I check if the database is unencrypted and then how can I encrypt it? Should I do this only once? What should be the best practice?

    (The possible duplicate doesn't answer this)

    3) When I encrypt my existing unencrypted database, do SQLCipher create a new database? If yes, how should I be managing this new one? And what about my old database which is unencrypted? Does it still stay there?

    (This explanation is also not provided in the duplicate question)

    解决方案

    How can I seamlessly integrate SQLCipher with my existing unencrypted database, so that my app works as it works normally but now the databases are encrypted?

    You don't. Among other things, you have to adjust your UI to ask the user for a passphrase, and ensure that you can ask for that passphrase as needed (e.g., user resumes a task from some "inner" activity, not just when the user runs your app via a launcher icon).

    I would like a short tutorial on this

    First, that is not how Stack Overflow works.

    Second, decent coverage of SQLCipher for Android takes much more than can fit in a single Stack Overflow answer. I have an 18-page chapter on the subject in my book, for example. This answer is already longer than the vast majority of Android questions, and I would not blame people for closing this question as being too broad.

    How should I check if the database is unencrypted

    Try opening it using the SQLCipher for Android classes with "" as the passphrase. If it opens successfully, the database is unencrypted. If that fails, either the database is corrupt or encrypted, and without the proper passphrase, you cannot tell the difference.

    how can I encrypt it?

    The basic approach is:

    • Open the unencrypted database

    • Use the ATTACH SQL statement to attach an empty file to serve as the new encrypted database, supplying your desired passphrase, and naming the attached database encrypted within your database session

    • Run the SELECT sqlcipher_export('encrypted') in the open (unencrypted) database, which will export the data from the unencrypted database into the encrypted one (with the exception of the database schema version, which is handled in later steps)

    • Call getVersion() on the open (unencrypted) database and hold onto that value for a bit

    • Close the unencrypted database

    • Open the encrypted database, using your passphrase

    • Call setVersion() on the encrypted database, supplying the value you cached from getVersion() of the unencrypted database

    • Close the encrypted database

    • If desired, delete the unencrypted database and rename the encrypted one to the name of the now-deleted unencrypted one, so that your conversion appears to happen in place

    This utility method implements the above approach:

      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);
        }
      }
    

    In the interests of full disclosure, I have not tried this in a while, and so there may need to be some tweaks.

    Should I do this only once?

    Only you can answer that, as nobody here is going to know much about your app.

    When I encrypt my existing unencrypted database, do SQLCipher create a new database?

    Yes.

    If yes, how should I be managing this new one?

    Only you can answer that, as nobody here is going to know much about your app.

    And what about my old database which is unencrypted? Does it still stay there?

    Yes, though you are welcome to delete it if and when you are done with it.

    这篇关于使用SQLCipher与Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆