【发布时间】:2014-08-01 12:06:30
【问题描述】:
我使用 SQLiteCipher 为我的应用程序数据库添加安全性,问题是,它比默认的 android SQLite API 太慢了。于是我切换回了默认的 SQLite API,但我确实需要 SQLCipher 提供的安全性,所以我做的是:
打开我的应用时
- 打开加密的数据库文件
- 创建一个普通的数据库文件
- 将记录从加密数据库传输到普通数据库
- 删除加密的数据库文件
- 使用普通的数据库文件
当我的应用关闭时,
- 打开正常的数据库文件
- 创建一个加密的数据库文件
- 将记录从普通数据库传输到加密数据库
- 删除正常的数据库文件
这没有任何问题,但是传输记录需要一些时间并且会消耗更多(我假设我的数据库文件在实际使用期间将包含数千条记录)。那么我所做的还有其他方式吗? 有没有更有效的方法来做到这一点?蒂亚!
编辑:这里是一些使用 SQLCipher 的代码
主要活动
private final static String phrase = "passW0rd3r";
private EditText StudNum, StudName, StudCrse;
private DBHelper dbIns;
SQLiteDatabase DBFile;
private MainDBHelper DBHelp;
private MenuItem msg_app;
final Context con = this;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StudNum = (EditText)findViewById(R.id.txtsNum);
StudName = (EditText)findViewById(R.id.txtsName);
StudCrse = (EditText)findViewById(R.id.txtCourse);
StudNum.requestFocus();
SQLiteDatabase.loadLibs(this);
dbIns = new DBHelper(this, DB_NAME);
DBFile = dbIns.getWritableDatabase(phrase);
DBHelp = new MainDBHelper(this);
//Takes too much time to load, loads around 3 seconds, compared to
//the default SQLite API, which is half a second only
}
MainDBHelper 类
public class MainDBHelper {
private static final String DB_NAME = "StudentInfo.db";
private static final String TABLE_NAME = "StudentInfo";
private final static String phrase = "passW0rd3r";
private DBHelper openHelper;
private SQLiteDatabase database;
public MainDBHelper(Context context) {
openHelper = new DBHelper(context, DB_NAME);
database = openHelper.getWritableDatabase(phrase);
}
}
DBHelper 类
public class DBHelper extends SQLiteOpenHelper{
private String DBName;
public DBHelper(Context context, String DBname) {
super(context, DBname, null, 5);
this.DBName = DBname.substring(0,DBname.length()-3);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
arg0.execSQL("CREATE TABLE " + DBName + " (_id INTEGER PRIMARY KEY, " +
"Stud_Num TEXT, Stud_Name TEXT, Stud_Crse TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
arg0.execSQL("DROP TABLE IF EXISTS " + DBName);
onCreate(arg0);
}
}
使用相同数据库连接的额外类
DisplayMessageActivity 类 - 这个加载大约 2 秒,只是为了在列表视图中显示 3 条记录。如果我使用默认的 SQLite API,它可以在一秒钟内加载多达 10 条记录
public class DisplayMessageActivity extends Activity {
private ListAdapter listAdapt;
private MainDBHelper DBHelp;
private EditText edtName, edtSnum, edtCrse;
private TextView dName, dSnum, dCrse, ssn;
private ListView lst_snum;
private SearchView sView;
private MenuItem sItem;
private View lView, diagView;
private AlertDialog.Builder DBuilder;
private AlertDialog ADiag;
private String StudentNumber, edSname, edSnum, edCrse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
DBHelp = new MainDBHelper(this);
lst_snum = (ListView)findViewById(R.id.lv_test);
refreshList();
createADiag(this);
lst_snum.setOnItemLongClickListener(new OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
lView = view;
ssn = (TextView)view.findViewById(R.id.studNum);
ADiag.show();
return false;
}
});
}
private void refreshList(){
listAdapt = null;
listAdapt = new ListAdapter(this, DBHelp.getTimeRecordList());
lst_snum.setAdapter(listAdapt);
}
}
更新:我已经阅读了一些与我的相关的问题,并且我真的看到有些问题还面临使用 SQLCipher 的性能问题,一个答案说“缓存数据库”只能用于一次连接,可以用于多个同一个应用程序上的活动,问题是,我不知道这样做
【问题讨论】:
-
“它比默认的 android SQLite API 太慢了”——我还没有听说过这方面的主要问题。加密开销并没有那么糟糕,因此如果使用 SQLCipher 很慢,那么使用普通 SQLite 可能会很慢(例如,强制表扫描的查询)。您可以考虑使用
PRAGMA cipher_profile进行试验,看看是否可以帮助您查明问题。而且由于Android中没有“应用已关闭”的概念,因此您提出的方法将无法可靠地工作。 -
嗯,我的代码似乎有些奇怪,那么如果你说它很快(我会用我的代码更新我的问题)。那 PRAGMA cipher_profile 是否需要我构建源代码?关于应用程序关闭的概念,我开发了我的应用程序,以便每当用户离开它时它会自动退出/完成(通过activityForResult),所以我想我的应用程序可以在完全退出之前加密数据库。感谢您的回答
-
为什么不简单地在退出时加密整个文件?并在启动时解密?
-
“PRAGMA cipher_profile 需要我构建源代码吗?” ——我不知道。 “我开发了我的应用程序,以便在用户离开它时(通过activityForResult)自动退出/完成,所以我猜我的应用程序可以在完全退出之前加密数据库”——不可靠。
-
@greenapps,你是什么意思?有代码吗?
标签: android database sqlite sqlcipher