Android-SQLCipher web服务器数据库未正确读取/解密

Android-SQLCipher web服务器数据库未正确读取/解密,android,database,encryption,sqlcipher,Android,Database,Encryption,Sqlcipher,我有一个应用程序,可以成功地从web服务器下载未加密的数据库,并将该数据库用于我的目的。但是,我知道这是不安全的,如果设备是根设备,第三方应用程序可以看到这个数据库。所以我决定用SQLCipher加密它 我的应用程序可以毫无问题地创建和读取自己的SQLCipher数据库。所以我接下来要做的就是在模拟器上运行相同的应用程序,使用adb拉取数据库,然后使用创建一个转储文件,然后压缩它。我还遵循了示例代码,该代码使应用程序能够从web服务器下载zip文件并使用它 但是,在应用程序下载并提取数据库之后,

我有一个应用程序,可以成功地从web服务器下载未加密的数据库,并将该数据库用于我的目的。但是,我知道这是不安全的,如果设备是根设备,第三方应用程序可以看到这个数据库。所以我决定用SQLCipher加密它

我的应用程序可以毫无问题地创建和读取自己的SQLCipher数据库。所以我接下来要做的就是在模拟器上运行相同的应用程序,使用adb拉取数据库,然后使用创建一个转储文件,然后压缩它。我还遵循了示例代码,该代码使应用程序能够从web服务器下载zip文件并使用它

但是,在应用程序下载并提取数据库之后,问题就会出现。在我看来,应用程序无法正确下载它,或者数据库没有解密

然而,在回顾数据库是如何从.db文件转换为.dmp文件到.zip文件时,我也开始认为,当shell命令
$sqlite3 sampleDB.dp.dump>DBDump.dmp
命令没有正确执行时,因为它是一个sqlite3命令,并且数据库已经加密(适用于Mac OSX的SQLite Database Browser 2.0表示db是加密的或不是数据库文件)。因此,由于它不是sqlite3数据库,转储文件创建不正确,因此应用程序无法正确解压缩和执行转储文件

我尝试的另一个解决方案是简单地上传.db文件并下载。但是,我没有成功

有人知道如何下载和解密SQLCipher数据库文件吗?

到目前为止,这些是我的代码(请注意,所有导入都是net.sqlcipher,而不是android.database.sqlite):

onCreate方法上调用的AsyncTask,它是启动下载的任务:

private class Connection extends AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d("Hi", "Download Commencing");
    }

    @Override
    protected String doInBackground(String... params) {
        myDroidSQLDatabase = new MyDroidSQLDatabase(LogInPage.this);
        myDroidSQLDatabase.open();
        Log.d("Hi", "Downloading");
        return "Executed!";
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Log.d("Hi", "Done Downloading.");
    }
}
这是我的MyDroidSQLiteOpenHelper类

public class MyDroidSQLiteOpenHelper extends SQLiteOpenHelper {
  private Context context;
  private static final String __DB_NAME = "system.db";
  private static final int __DB_VERSION = 1;

  public MyDroidSQLiteOpenHelper(Context context) {
    super(context, __DB_NAME, null, __DB_VERSION);
    this.context=context;
  }

  @Override
  public void onCreate(SQLiteDatabase sqlLiteDb) {
    try {
      SQLiteDBDeploy.deploy(sqlLiteDb,"http://192.168.1.4/dbtest/system.db");
    } catch (IOException e) {
        //Log.e(MyDBAppActivity.TAG,e.getMessage(),e);
        throw new Error(e.getMessage());
    }
  }

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

  }
}
下面是SQLiteDBDeploy类:

public class SQLiteDBDeploy {
  private static final String TAG = "SQLiteDBDeploy";
  private static List<String> ignoreSQLs;

  static {
    ignoreSQLs = new LinkedList<String>();
    ignoreSQLs.add("--");
    ignoreSQLs.add("begin transaction;");
    ignoreSQLs.add("commit;");
    ignoreSQLs.add("create table android_metadata (locale text);");
    ignoreSQLs.add("create table \"android_metadata\" (locale text);");
    ignoreSQLs.add("insert into android_metadata values('en_us');");
    ignoreSQLs.add("insert into \"android_metadata\" values('en_us');");
  }  

  /**
   * Deploys given zip file in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param context
   *            to use to open or create the database
   * @param dbName
   *            dump zip file
   * @throws IOException
   */
  public static void deploy(SQLiteDatabase sqlLiteDb, Context context, String dbName) throws IOException {
    Log.i(TAG, "reading zip file: " + dbName);
    InputStream dbStream = context.getAssets().open(dbName);

    deploy(sqlLiteDb, dbStream);

    dbStream.close();
  }

  /**
   * Deploys given zip file url in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param dbUrl
   *            dump zip file url
   * @throws IOException
   */
  public static void deploy(SQLiteDatabase sqlLiteDb, String dbUrl) throws IOException {
    Log.i(TAG, "reading url: " + dbUrl);

    HttpURLConnection c = (HttpURLConnection) new URL(dbUrl).openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    InputStream dbStream = c.getInputStream();

    deploy(sqlLiteDb, dbStream);

    dbStream.close();
    c.disconnect();
  } 

  /**
   * Deploys given dump  file stream in SQLiteDatabase
   * 
   * @param sqlLiteDb the database
   * @param dbStream stream to read dump data 
   * @throws IOException
   */
  private static void deploy(SQLiteDatabase sqlLiteDb, InputStream dbStream) throws IOException {
    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(dbStream));
    ZipEntry entry = null;


    while ((entry = zis.getNextEntry()) != null) {
        Log.i(TAG, "deploying zip entry: " + entry);
        InputStreamReader dbReader = new InputStreamReader(zis);
        deploy(sqlLiteDb, dbReader);
    }
  }

  /**
   * Deploys given stream in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param dbReader
   *            stream to read dump SQL statements
   * @throws IOException
   * @throws SQLException
   */
  private static void deploy(SQLiteDatabase sqlLiteDb, InputStreamReader dbReader) throws IOException {
    String sqlLine = null;
    StringBuffer sqlBuffer = new StringBuffer();
    BufferedReader bufferedReader = new BufferedReader(dbReader);

    sqlLiteDb.beginTransaction();

    try {
        while ((sqlLine = bufferedReader.readLine()) != null) {
            String sql = sqlLine.trim();
            if (!isIgnoreSQL(sql)) {
                if (sql.endsWith(";")) {
                    sqlBuffer.append(sql);
                    String execSQL = sqlBuffer.toString();
                    Log.d(TAG, "running sql=>" + execSQL);
                    sqlLiteDb.execSQL(execSQL);
                    sqlBuffer.delete(0, sqlBuffer.length());
                } else {
                    if (sqlBuffer.length() > 0) {
                        sqlBuffer.append(' ');
                    }
                    sqlBuffer.append(sql);
                }
            }
        }
        sqlLiteDb.setTransactionSuccessful();
    } finally {
        sqlLiteDb.endTransaction();
    }
  }

  /**
   * Returns true if the given SQL statement is to be ignored
   * @param sql SQL statement
   * @return
   */
    private static boolean isIgnoreSQL(String sql) {
    if (sql.length() == 0) {
        return true;
    }

    String lowerSQL = sql.toLowerCase();
    for (String ignoreSQL : ignoreSQLs) {
        if (lowerSQL.startsWith(ignoreSQL)) {
            return true;
        }
    }
    return false;
  }
}
公共类SQLiteDBDeploy{
私有静态最终字符串TAG=“SQLiteDBDeploy”;
私有静态列表ignoreSQLs;
静止的{
ignoreSQLs=新建LinkedList();
ignoreSQLs.add(“--”);
添加(“开始事务;”;
ignoreSQLs.add(“commit;”);
add(“创建表android_元数据(区域设置文本);”;
add(“创建表\”android_元数据\“(区域设置文本);”;
add(“插入到android_元数据值('en_us');”;
add(“插入到\“android_元数据\”值('en_us');”;
}  
/**
*在SQLiteDatabase中部署给定的zip文件
* 
*@param sqlLiteDb
*数据库
*@param上下文
*用于打开或创建数据库的步骤
*@param dbName
*转储压缩文件
*@抛出异常
*/
公共静态void部署(SQLiteDatabase sqlLiteDb、上下文上下文、字符串dbName)引发IOException{
Log.i(标记“读取zip文件:”+dbName);
InputStream dbStream=context.getAssets().open(dbName);
部署(sqlLiteDb、dbStream);
dbStream.close();
}
/**
*在SQLiteDatabase中部署给定的zip文件url
* 
*@param sqlLiteDb
*数据库
*@param dbUrl
*转储压缩文件url
*@抛出异常
*/
公共静态void部署(SQLiteDatabase sqlLiteDb,String dbUrl)引发IOException{
Log.i(标记“读取url:+dbUrl”);
HttpURLConnection c=(HttpURLConnection)新URL(dbUrl).openConnection();
c、 setRequestMethod(“GET”);
c、 设置输出(真);
c、 connect();
InputStream dbStream=c.getInputStream();
部署(sqlLiteDb、dbStream);
dbStream.close();
c、 断开连接();
} 
/**
*在SQLiteDatabase中部署给定的转储文件流
* 
*@param sqlLiteDb数据库
*@param dbStream流读取转储数据
*@抛出异常
*/
私有静态void部署(SQLiteDatabase sqlLiteDb,InputStream dbStream)引发IOException{
ZipInputStream zis=新的ZipInputStream(新的BufferedInputStream(dbStream));
ZipEntry条目=null;
而((entry=zis.getNextEntry())!=null){
Log.i(标记“部署zip条目:”+条目);
InputStreamReader dbReader=新的InputStreamReader(zis);
部署(sqlLiteDb、dbReader);
}
}
/**
*在SQLiteDatabase中部署给定流
* 
*@param sqlLiteDb
*数据库
*@param dbReader
*流以读取转储SQL语句
*@抛出异常
*@SQLException
*/
私有静态void部署(SQLiteDatabase sqlLiteDb,InputStreamReader dbReader)引发IOException{
字符串sqlLine=null;
StringBuffer sqlBuffer=新的StringBuffer();
BufferedReader BufferedReader=新的BufferedReader(dbReader);
sqlLiteDb.beginTransaction();
试一试{
而((sqlLine=bufferedReader.readLine())!=null){
字符串sql=sqlLine.trim();
如果(!isIgnoreSQL(sql)){
if(sql.endsWith(“;”)){
追加(sql);
字符串execSQL=sqlBuffer.toString();
Log.d(标记“running sql=>”+execSQL);
sqlLiteDb.execSQL(execSQL);
删除(0,sqlBuffer.length());
}否则{
if(sqlBuffer.length()>0){
sqlBuffer.append(“”);
}
追加(sql);
}
}
}
sqlLiteDb.setTransactionSuccessful();
}最后{
sqlLiteDb.endTransaction();
}
}
/**
*如果要忽略给定的SQL语句,则返回true
*@param-sql语句
*@返回
*/
私有静态布尔值isIgnoreSQL(字符串sql){
if(sql.length()==0){
返回true;
}
String lowerSQL=sql.toLowerCase();
for(字符串ignoreSQL:ignoreSQLs){
public class SQLiteDBDeploy {
  private static final String TAG = "SQLiteDBDeploy";
  private static List<String> ignoreSQLs;

  static {
    ignoreSQLs = new LinkedList<String>();
    ignoreSQLs.add("--");
    ignoreSQLs.add("begin transaction;");
    ignoreSQLs.add("commit;");
    ignoreSQLs.add("create table android_metadata (locale text);");
    ignoreSQLs.add("create table \"android_metadata\" (locale text);");
    ignoreSQLs.add("insert into android_metadata values('en_us');");
    ignoreSQLs.add("insert into \"android_metadata\" values('en_us');");
  }  

  /**
   * Deploys given zip file in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param context
   *            to use to open or create the database
   * @param dbName
   *            dump zip file
   * @throws IOException
   */
  public static void deploy(SQLiteDatabase sqlLiteDb, Context context, String dbName) throws IOException {
    Log.i(TAG, "reading zip file: " + dbName);
    InputStream dbStream = context.getAssets().open(dbName);

    deploy(sqlLiteDb, dbStream);

    dbStream.close();
  }

  /**
   * Deploys given zip file url in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param dbUrl
   *            dump zip file url
   * @throws IOException
   */
  public static void deploy(SQLiteDatabase sqlLiteDb, String dbUrl) throws IOException {
    Log.i(TAG, "reading url: " + dbUrl);

    HttpURLConnection c = (HttpURLConnection) new URL(dbUrl).openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    InputStream dbStream = c.getInputStream();

    deploy(sqlLiteDb, dbStream);

    dbStream.close();
    c.disconnect();
  } 

  /**
   * Deploys given dump  file stream in SQLiteDatabase
   * 
   * @param sqlLiteDb the database
   * @param dbStream stream to read dump data 
   * @throws IOException
   */
  private static void deploy(SQLiteDatabase sqlLiteDb, InputStream dbStream) throws IOException {
    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(dbStream));
    ZipEntry entry = null;


    while ((entry = zis.getNextEntry()) != null) {
        Log.i(TAG, "deploying zip entry: " + entry);
        InputStreamReader dbReader = new InputStreamReader(zis);
        deploy(sqlLiteDb, dbReader);
    }
  }

  /**
   * Deploys given stream in SQLiteDatabase
   * 
   * @param sqlLiteDb
   *            the database
   * @param dbReader
   *            stream to read dump SQL statements
   * @throws IOException
   * @throws SQLException
   */
  private static void deploy(SQLiteDatabase sqlLiteDb, InputStreamReader dbReader) throws IOException {
    String sqlLine = null;
    StringBuffer sqlBuffer = new StringBuffer();
    BufferedReader bufferedReader = new BufferedReader(dbReader);

    sqlLiteDb.beginTransaction();

    try {
        while ((sqlLine = bufferedReader.readLine()) != null) {
            String sql = sqlLine.trim();
            if (!isIgnoreSQL(sql)) {
                if (sql.endsWith(";")) {
                    sqlBuffer.append(sql);
                    String execSQL = sqlBuffer.toString();
                    Log.d(TAG, "running sql=>" + execSQL);
                    sqlLiteDb.execSQL(execSQL);
                    sqlBuffer.delete(0, sqlBuffer.length());
                } else {
                    if (sqlBuffer.length() > 0) {
                        sqlBuffer.append(' ');
                    }
                    sqlBuffer.append(sql);
                }
            }
        }
        sqlLiteDb.setTransactionSuccessful();
    } finally {
        sqlLiteDb.endTransaction();
    }
  }

  /**
   * Returns true if the given SQL statement is to be ignored
   * @param sql SQL statement
   * @return
   */
    private static boolean isIgnoreSQL(String sql) {
    if (sql.length() == 0) {
        return true;
    }

    String lowerSQL = sql.toLowerCase();
    for (String ignoreSQL : ignoreSQLs) {
        if (lowerSQL.startsWith(ignoreSQL)) {
            return true;
        }
    }
    return false;
  }
}