2017-04-26 3 views
0

私は何年間も生産されているアプリを持っています。標準のSqlite DBが付属しています。アプリの最新バージョンにはSqlCipher 3.5.6ライブラリが統合されています。ファイルが暗号化されているかデータベースではありません:コンパイル中に:select count(*)from sqlite_master;

新しいDBにいくつかの余分なテーブルがあるので、それらをonUpgradeメソッドで作成しました。

私はアプリケーションオブジェクトで次のメソッドを呼び出しました。

SQLiteDatabase.loadLibs(this); 

古いAPKでDB_VERSIONは56で、ONUPGRADEを呼び出さなければなりませんので、私は、新しいAPKで57に設定しています。

私はonUpgradeの中からencryptメソッドを呼び出します。

@Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

      Log.e(TAG, "++++++++++++++++++++++++++SQLiteOpenHelper onUpgrade old version = " + oldVersion + " new version = " + newVersion); 

if(oldVersion == 56){ 

       String sqlToCreateWeeklySummary = String 
         .format("create table %s (%s INTEGER primary key, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)", 
           TABLEWEEKLYSUMMARY, C_ID_WEEKLY_SUMMARY, C_WEEKLY_SUMMARY_STARTDATE, 
           C_WEEKLY_SUMMARY_PLANNEDCALLS, C_WEEKLY_SUMMARY_NCR, C_WEEKLY_SUMMARY_QA, C_WEEKLY_SUMMARY_PLANNEDHOURS, 
           C_WEEKLY_SUMMARY_ACTUALCALLS, C_WEEKLY_SUMMARY_ACTUALHOURS); 

       db.execSQL(sqlToCreateWeeklySummary); 
       Log.e(TAG, "onUpgrade " + sqlToCreateWeeklySummary); 


more table upgrades................ 

       NfcScannerApplication.setJustUpgradedDBTrue(); 
       NfcScannerApplication.setDownloadingCompOptsAfterUpgradeTrue(); 




       try { 
        encrypt(context, "carefreemobiledb.db", ""); 
       }catch(Exception e){} 

      } 



     }//end of onUpgrade 

public void encrypt(Context ctxt, String dbName, String passphrase) throws IOException { 

     Log.e(TAG, "inside encrypt"); 

     File originalFile=ctxt.getDatabasePath(dbName); 

     if (originalFile.exists()) { 
      Log.e(TAG, "originalFile exists1"); 
      File newFile= File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir()); 
      Log.e(TAG, "created newFile2"); 

      SQLiteDatabase db= SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), 
        "", null, SQLiteDatabase.OPEN_READWRITE); 
      Log.e(TAG, "opened DB using originalFile3"); 

      db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", 
        newFile.getAbsolutePath(), passphrase)); 
      Log.e(TAG, "Attached DB4"); 

      db.rawExecSQL("SELECT sqlcipher_export('encrypted')"); 

      Log.e(TAG, "export5"); 

      db.rawExecSQL("DETACH DATABASE encrypted;"); 
      Log.e(TAG, "detached DB6"); 

      int version=db.getVersion(); 

      db.close(); 
      Log.e(TAG, "closed DB7"); 

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

      Log.e(TAG, "opened DB with newFile8"); 

      db.setVersion(version); 
      Log.e(TAG, "set version for db using newFile9"); 
      db.close(); 
      Log.e(TAG, "closed db10"); 

      originalFile.delete(); 
      Log.e(TAG, "deleted orignial file11"); 
      newFile.renameTo(originalFile); 
      Log.e(TAG, "renamed newFile to orginalFile12"); 
     } 
    } 

古いアプリがインストールされているデバイスに新しいapkを読み込むと、次のエラーが表示されます。

file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master; 
              net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master; 
               at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method) 
               at net.sqlcipher.database.SQLiteCompiledSql.compile(Unknown Source) 
               at net.sqlcipher.database.SQLiteCompiledSql.<init>(Unknown Source) 
               at net.sqlcipher.database.SQLiteProgram.<init>(Unknown Source) 
               at net.sqlcipher.database.SQLiteQuery.<init>(Unknown Source) 
               at net.sqlcipher.database.SQLiteDirectCursorDriver.query(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.rawQuery(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.keyDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteOpenHelper.getReadableDatabase(Unknown Source) 
               at com.carefreegroup.rr3.g.c(Unknown Source) 
               at com.carefreegroup.rr3.EntryActivity.onCreate(Unknown Source) 
               at android.app.Activity.performCreate(Activity.java:6912) 
               at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126) 
               at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2900) 
               at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008) 
               at android.app.ActivityThread.-wrap14(ActivityThread.java) 
               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650) 
               at android.os.Handler.dispatchMessage(Handler.java:102) 
               at android.os.Looper.loop(Looper.java:154) 
               at android.app.ActivityThread.main(ActivityThread.java:6688) 
               at java.lang.reflect.Method.invoke(Native Method) 
               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 
04-26 10:40:53.332 9417-9417/? E/SQLiteOpenHelper: Couldn't open carefreemobiledb.db for writing (will try read-only): 

は私がしようとしているもの:SO上

他の記事は、暗号化方式のパスワードがSqlCipherは暗号化されていないDBを開くことができるように、空の文字列にする必要があると言います。

encryptメソッドでパスワードを「」に設定しましたが、ログにDBを開くことができませんでした。

誰でもDBが開かれていない理由を教えていただけますか? onUpgradeメソッドまでは到達していません。

NB。それは私がアプリのデータをクリアすると、それはうまく動作することに注意する価値があるかもしれません。

[更新1]

私は、暗号化メソッドをApplicationクラスに移動しました。 ApplicationクラスのonCreateでは、

を呼び出します。

パスフレーズの暗号化メソッドに空のStringパラメータがありますが、以下の実際の暗号化メソッドでコメントアウトしているので、何もしません。

public static void encrypt(Context ctxt, String dbName, String passphrase) throws IOException { 

     File originalFile=ctxt.getDatabasePath(dbName); 

     if (originalFile.exists()) { 
      Log.e(TAG, "originalFile exists1"); 
      File newFile= File.createTempFile("sqlcipherutils", "tmp", ctxt.getCacheDir()); 
      Log.e(TAG, "created newFile2"); 

      SQLiteDatabase db= SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(), 
          "", null, SQLiteDatabase.OPEN_READWRITE); 
      Log.e(TAG, "opened DB using originalFile3"); 

//   db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", 
//     newFile.getAbsolutePath(), passphrase)); 
      db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", 
        newFile.getAbsolutePath())); 
      Log.e(TAG, "Attached DB4"); 

      db.rawExecSQL("SELECT sqlcipher_export('encrypted')"); 

      Log.e(TAG, "export5"); 

      db.rawExecSQL("DETACH DATABASE encrypted;"); 
      Log.e(TAG, "detached DB6"); 

      int version=db.getVersion(); 

      db.close(); 
      Log.e(TAG, "closed DB7"); 

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

      Log.e(TAG, "opened DB with newFile8"); 

      db.setVersion(version); 
      Log.e(TAG, "set version for db using newFile9"); 
      db.close(); 
      Log.e(TAG, "closed db10"); 

      originalFile.delete(); 
      Log.e(TAG, "deleted orignial file11"); 
      newFile.renameTo(originalFile); 
      Log.e(TAG, "renamed newFile to orginalFile12"); 
     } 
    } 

04-26 13:56:02.793 15460-15460/? E/NfcScannerApplication: just called SQLiteDatabase.loadLibs(this) 
04-26 13:56:02.793 15460-15460/? E/NfcScannerApplication: originalFile exists1 
04-26 13:56:02.794 15460-15460/? E/NfcScannerApplication: created newFile2 
04-26 13:56:02.798 15460-15460/? E/NfcScannerApplication: opened DB using originalFile3 
04-26 13:56:02.806 3247-3247/? E/audit: type=1320 audit(1493211362.789:23690): 
04-26 13:56:02.817 3247-3247/? E/audit: type=1320 audit(1493211362.799:23691): 
04-26 13:56:02.828 3247-3247/? E/audit: type=1320 audit(1493211362.809:23692): 
04-26 13:56:02.886 15460-15469/? E/Database: close() was never explicitly called on database '/data/user/0/com.carefreegroup.rr3/databases/carefreemobiledb.db' 
              net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
               at net.sqlcipher.database.SQLiteDatabase.<init>(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source) 
               at net.sqlcipher.database.SQLiteDatabase.openDatabase(Unknown Source) 
               at com.carefreegroup.rr3.NfcScannerApplication.a(Unknown Source) 
               at com.carefreegroup.rr3.NfcScannerApplication.onCreate(Unknown Source) 
               at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1032) 
               at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5881) 
               at android.app.ActivityThread.-wrap3(ActivityThread.java) 
               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1718) 
               at android.os.Handler.dispatchMessage(Handler.java:102) 
               at android.os.Looper.loop(Looper.java:154) 
               at android.app.ActivityThread.main(ActivityThread.java:6688) 
               at java.lang.reflect.Method.invoke(Native Method) 
               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 

は、私は今、次のエラーを取得します。

それは、次のとクラッシュ限り取得します。

Log.e(TAG, "opened DB using originalFile3"); 

[更新2]

データベースを正しく閉じるかどうかわかりません。 LoginValidateはDBオブジェクトを返すメソッドが公開されている私のDBクラスです。

SQLiteDatabase.loadLibs(this); 
     Log.e(TAG, "just called SQLiteDatabase.loadLibs(this)"); 

     loginValidate.getDB().close(); 

     try { 
      encrypt(mContext, "carefreemobiledb.db", ""); 
     }catch(Exception e){} 

また、私はencryptメソッドのパスフレーズについてはわかりません。あなたはパスフレーズを使わないと言っていますが、それは意味のある空文字列かパスフレーズをまったく通過しません。私は次の例を挙げます。最初はオリジナル、もう1つは私が試したものです。

Log.e(TAG, "opened DB using originalFile3"); 

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




Log.e(TAG, "opened DB using originalFile3"); 

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



Log.e(TAG, "opened DB using originalFile3"); 

      db.rawExecSQL(String.format("ATTACH DATABASE '%s';", 
        newFile.getAbsolutePath())); 
+0

私が正しく読んでいれば、 '... AS暗号化されたKEY ...'呼び出しの置換バージョンは明示的に '、' '' '.getAbsolutePath()'の後ろに置かれなければなりません。 'String.format()'の 's'はランダムな文字列をスタックから引き出します。 – TripeHound

+0

@TripeHoundありがとうございますが、私はまだパスフレーズを使用しないことが何を意味するのか分かりません。私は更新2の下の投稿を編集しました – turtleboy

+0

どちらも私はいません。ちょうどその少しのコードはおそらくうまくいかなかったでしょう。 – TripeHound

答えて

0

Can anyone tell me why the DB is not being opened?

データベースが暗号化されていないので、あなたはパスフレーズでそれを開こうとしている、それが動作していないので。 Android用のSQLCipherは、今度はパスフレーズなしでデータベースをもう一度開こうとすることを魔法のように決めるのではなく、onUpgrade()を呼び出します。

さらに、どのようにこの状態になっていますか?ユーザーからパスフレーズを収集する必要があります。ユーザーは、一度も設定していないパスフレーズを突然開始すると面倒なことに気付くでしょう。代わりに、ユーザがパスフレーズを設定してencrypt()を通過する「暗号化されたデータベースに切り替えましょう!」という特定のUXが必要です。

+0

こんにちはマーク、パスフレーズはApplicationオブジェクトでハードコードされていますが、これは実行すべきではありませんが、これを取得しようとしています。最終的に私は暗号のパスフレーズとしてユーザーのログインパスワードを使用します。 – turtleboy

+0

@turtleboy:それにかかわらず、暗号化されていないものから 'onUpgrade()'で暗号化に切り替えることはできません。 'onUpgrade()'は、データベースが開かれた後*と呼ばれます。閉じたデータベースで 'encrypt()'を使う必要があります。 – CommonsWare

+0

投稿[編集1]を編集しました。あなたは時間があれば見てみることができますか? – turtleboy

関連する問題