[Android初级]使用Sqlcipher对sqlite数据库进行加解密

在Android学习和开发的过程中,你我都可能遇到这样的问题,android系统的sqlite数据库文件中的信息如何保证不会被恶意窃取或者暴露,这个时候我觉得可以选择这几个思路:1.程序本身在操作数据库的时候,对字段进行加密;2.对整个数据库文件进行加密。我是根据后者的情况,推荐一种方式,就是使用Sqlcipher对SQLite进行数据库的加密操作,而且Sqlcipher本身也是开源的。

看我如何使用它吧!

(1)首先,官网的地址:http://sqlcipher.net/open-source/ ,你可以直接点击下载SQLCipher+for+Android+v3.0.2.zip

下载之后是含libs和assets的文件夹,我们只要对应的把里面的文件拷贝到android项目中即可。(友情提示:文件比较大,会直接影响项目->apk文件的大小,如果在限制apk大小的条件下,请慎用!)

(2)开是创建我的测试项目SQLCipherTest,项目结构如下:

[Android初级]使用Sqlcipher对sqlite数据库进行加解密_第1张图片

(3)代码部分跟android的开发方式一致(使用SQLiteOpenHelper来管理数据库),稍有一些不同,看代码:

类:ExDataBaseHelper

/**
 *   * 管理数据库的工具类   *   * @author jan
 */
public class ExDataBaseHelper extends SQLiteOpenHelper {
	private static final String DATABASE_NAME = "example.db";
	private static final int DATABASE_VERSION = 1;
	
	//读写数据库用到的password
	public static final String SECRET_KEY="test_key";
	public static final String TABLE_NAME = "user";

	/**
	 * 用户表
	 */
	private String CREATE_TABLE_USER = "create table " + TABLE_NAME
			+ "(_id integer primary key autoincrement,"
			+ "userName varchar(50) UNIQUE," + "userPwd varchar(50),"
			+ "email varchar(50) UNIQUE," + "phoneNum varchar(50) UNIQUE,"
			+ "userNiName varchar(60))";

	public ExDataBaseHelper(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// 第一次使用数据库时自动建表
		db.execSQL(CREATE_TABLE_USER);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		if (oldVersion >= newVersion)
			return;

		String sql = null;
		if (oldVersion == 1)
			sql = "alter table " + CREATE_TABLE_USER + " add note text;";
		if (oldVersion == 2)
			sql = "";

		Log.d("EventsData", "onUpgrade	: " + sql);
		if (sql != null)
			db.execSQL(sql);
	}
}

类:MainActivity

public class MainActivity extends Activity implements OnClickListener {
	
	private static final String TAG=MainActivity.class.getSimpleName();

	private ExDataBaseHelper dbHelper;
	private SQLiteDatabase db;
	private User mUser;

	private Button addUserButton;
	private Button showUserButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		addUserButton = (Button) findViewById(R.id.add_user_button);
		addUserButton.setOnClickListener(this);
		showUserButton = (Button) findViewById(R.id.show_button);
		showUserButton.setOnClickListener(this);
		// 首先必须要调用库文件
		SQLiteDatabase.loadLibs(this);
		dbHelper = new ExDataBaseHelper(this);
		mUser = new User("jan", "白色超人", "uwontknow", "[email protected]", "110");
		// 根据一个“密钥”获取一个数据库操作对象
		db = dbHelper.getWritableDatabase(ExDataBaseHelper.SECRET_KEY);

	}

	private void addUser(SQLiteDatabase db, User user) {
		ContentValues values = new ContentValues();
		values.put("userName", user.getUserName());
		values.put("userPwd", user.getUserPwd());
		values.put("email", user.getEmail());
		values.put("phoneNum", user.getPhoneNum());
		values.put("userNiName", user.getUserNiName());
		long rowid = db.insert(ExDataBaseHelper.TABLE_NAME, null, values);
		Log.d(TAG, "DB insert rowId="+rowid);
	}

	private User queryUser(SQLiteDatabase db) {
		User user = new User();
		Cursor cursor = db.query(ExDataBaseHelper.TABLE_NAME,
				new String[] { "_id,userName,userPwd,email,phoneNum,userNiName" },
				"userName=? and userPwd=?",
				new String[] { "jan", "uwontknow" }, null, null, null);
		if(cursor!=null){
			startManagingCursor(cursor);
			Log.d(TAG, "cursor.count=>"+cursor.getCount());
			cursor.moveToFirst();
			user.setId(cursor.getInt(cursor.getColumnIndex("_id")));
			user.setUserName(cursor.getString(cursor.getColumnIndex("userName")));
			user.setUserPwd(cursor.getString(cursor.getColumnIndex("userPwd")));
			user.setEmail(cursor.getString(cursor.getColumnIndex("email")));
			user.setPhoneNum(cursor.getString(cursor.getColumnIndex("phoneNum")));
			user.setUserNiName(cursor.getString(cursor.getColumnIndex("userNiName")));
		}
		return user;
	}

	@Override
	protected void onDestroy() {
		if (db != null) {
			db.close();
		}
		if (dbHelper != null) {
			dbHelper.close();
		}
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		if (v == addUserButton) {
			addUser(db, mUser);
		} else if (v == showUserButton) {
			User user = queryUser(db);
			Toast.makeText(MainActivity.this, user.toString(),
					Toast.LENGTH_LONG).show();
		}
	}
}

(4)当我点击插入数据后,我在黑窗口打开example.db,查看数据表,结果是打不开的。

如下效果。

[Android初级]使用Sqlcipher对sqlite数据库进行加解密_第2张图片

(5)查看刚才插入的数据:

[Android初级]使用Sqlcipher对sqlite数据库进行加解密_第3张图片


使用之后,我感觉这个第三方so文件和jar文件多还占空间,这个是比较不爽的,建议根据不同的情景选择加密方式吧!

可参考源代码:示例项目下载

你可能感兴趣的:(android,数据库,加密,sqlite)