2015-06-03 4 views
0

У меня есть приложение для Android, которое использует SQLCipher для шифрования базы данных. Приложение заработало и имеет много активных пользователей. Я ищу решение, которое может удалить шифрование SQLCipher из существующей базы данных приложения без потери данных пользователя.Удалить шифрование SQLCipher из базы данных моего существующего приложения

Я попытался сделать обратное тому, что упоминается в сообщении this, но не смог открыть файл зашифрованной базы данных.

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

     File originalFile = ctxt.getDatabasePath(dbName); 

     int version = 0; 
     if (originalFile.exists()) { 
      File newFile = File.createTempFile("sqlite", "tmp", ctxt.getCacheDir()); 

      net.sqlcipher.database.SQLiteDatabase dbCipher = net.sqlcipher.database.SQLiteDatabase.openDatabase(
        originalFile.getAbsolutePath(), passphrase, null, 
        net.sqlcipher.database.SQLiteDatabase.OPEN_READWRITE); 

      if (dbCipher.isOpen()) { 
       dbCipher.rawExecSQL(String.format(
         "ATTACH DATABASE '%s' AS plaintext KEY '%s';", 
         newFile.getAbsolutePath(), passphrase)); 
       dbCipher.rawExecSQL("SELECT sqlcipher_export('plaintext')"); 
       dbCipher.rawExecSQL("DETACH DATABASE plaintext;"); 

       version = dbCipher.getVersion(); 

       dbCipher.close(); 
      } 


      SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(newFile, null); 
      db.setVersion(version); 
      db.close(); 

      originalFile.delete(); 
      newFile.renameTo(originalFile); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

И вот журналы ошибок, которые я получил ...

06-04 11:33:54.929: E/SQLiteLog(12309): (26) file is encrypted or is not a database 
06-04 11:33:54.929: E/DefaultDatabaseErrorHandler(12309): Corruption reported by sqlite on database: /data/data/ril.jio.protrak/cache/sqlite1817652413tmp 
+3

Создание регулярной базы данных SQLite, откройте SQLCipher и скопировать данные из базы данных SQLCipher в базу данных SQLite. Это будет обратный метод 'encrypt()', который я покажу [в этом ответе переполнения стека] (https://stackoverflow.com/a/29867682/115145). – CommonsWare

+0

, если вы просто хотите расшифровать db и продолжать использовать sqlcipher lib, я думаю, вы можете просто «переустановить» db с пустым новым паролем, но если вы хотите перейти к интегрированному с Android-сайтом sqlite, вы должны принять подход перенос данных из старой в новую БД. – Yazan

ответ

1

Вот пример экспортировать SQLCipher зашифрованный файл базы данных в простом текстовом файле базы данных.

Revert назад

import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 

Вместо

import net.sqlcipher.Cursor; 
import net.sqlcipher.database.SQLiteDatabase; 
import net.sqlcipher.database.SQLiteOpenHelper; 

Теперь использовать этот класс, чтобы экспортировать зашифрованный файл базы данных в обычном формате обычного текста

import java.io.File; 
     import java.io.FileInputStream; 
     import java.io.FileOutputStream; 
     import java.io.InputStream; 
     import java.io.OutputStream; 
     import android.content.Context; 
     import android.os.AsyncTask; 
     import android.util.Log; 

    public class ExportSQLCipherEncryptedDBIntoPlainText extends 
      AsyncTask<Void, Integer, Boolean> { 

     private Context context; 
     private String dbName, password, filePath; 

     public ExportSQLCipherEncryptedDBIntoPlainText(Context context, 
       String dbName, String password, String filePath) { 

      this.context = context; 
      this.dbName = dbName; 
      this.password = password; 
      this.filePath = filePath; 

     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
     } 

     @Override 
     protected Boolean doInBackground(Void... arg0) { 

      try { 

       File originalFile = context.getDatabasePath(dbName); 

       int version = 0; 
       if (originalFile.exists()) { 

        // create new file 
        File newFile = new File(filePath + "/plaintext.db"); 
        File newAdditionalFile = new File(filePath + "/plaintext.db-journal"); 
        if (!newFile.exists()) { 

         net.sqlcipher.database.SQLiteDatabase.loadLibs(context); 
         net.sqlcipher.database.SQLiteDatabase dbCipher = net.sqlcipher.database.SQLiteDatabase 
           .openDatabase(
             originalFile.getAbsolutePath(), 
             password, 
             null, 
             net.sqlcipher.database.SQLiteDatabase.OPEN_READWRITE); 

         if (dbCipher.isOpen()) { 
          dbCipher.rawExecSQL("ATTACH DATABASE '" + filePath 
            + "/plaintext.db' AS plaintext KEY ''"); 
          dbCipher.rawExecSQL("SELECT sqlcipher_export('plaintext')"); 
          dbCipher.rawExecSQL("DETACH DATABASE plaintext"); 
          version = dbCipher.getVersion(); 
          dbCipher.close(); 
         } 

         if (newFile.exists()) { 
          android.database.sqlite.SQLiteDatabase db = android.database.sqlite.SQLiteDatabase 
            .openOrCreateDatabase(newFile, null); 
          db.setVersion(version); 
          db.close(); 
          originalFile.delete(); 
          // newFile.renameTo(originalFile); 
         } 

         Log.i("AndroidLib", 
           "Copying database from external directory to application Started"); 
         byte[] buffer = new byte[1024]; 
         OutputStream myOutput = null; 
         int length; 
         // Open your local db as the input stream 
         InputStream myInput = null; 
         myInput = new FileInputStream(newFile); 
         // transfer bytes from the inputfile to the 
         // outputfile 
         myOutput = new FileOutputStream(originalFile); 
         while ((length = myInput.read(buffer)) > 0) { 
          myOutput.write(buffer, 0, length); 
         } 

         myOutput.flush(); 
         myOutput.close(); 
         myInput.close(); 

         if (originalFile.exists()) { 

          android.database.sqlite.SQLiteDatabase db = android.database.sqlite.SQLiteDatabase 
            .openOrCreateDatabase(originalFile, null); 

          newFile.delete(); 

          if (newAdditionalFile.exists()) { 
           newAdditionalFile.delete(); 
          } 

          Log.i("AndroidLib", 
            "Copying database from external directory to application Completed successfully"); 
         } 



        } 

       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      return true; 
     } 

     @Override 
     protected void onPostExecute(Boolean result) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(result); 
     } 

    }