Android 使用Sqlcipher给Sqlite加密

Android 系统的Sqlite数据库是一个轻量级且没有加密功能的数据库,但有时候我们的数据库保存了一些重要的信息,不想让别人知道,就需要对数据库加密。但大多数的加密都需要收费的,而Sqlcipher是免费的。下面我们用sqlcipher来加密数据库。

一、配置工程

注意assets下的文件
jar包

二、加载so

我们在Application加载so,别忘记将Application配置到Manifest文件中

package com.huang.sqlcipher;
//注意导包
import net.sqlcipher.database.SQLiteDatabase;
import android.app.Application;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        //加载so
        SQLiteDatabase.loadLibs(MyApplication.this);
    }

}

三、加密

注:输入的密码在第一次生效,后期无法修改,当密码为空时,相当于没有加密的数据库

1.我们可以用

 SQLiteDatabase.openOrCreateDatabase(file, password, factory)

来获取SQLiteDatabase进行操作
2.也可以对/data/data下数据库进行加密
SqlDbHelper类

package com.huang.sqlcipher;

import android.content.Context;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabase.CursorFactory;
import net.sqlcipher.database.SQLiteOpenHelper;

public class SqlDbHelper extends SQLiteOpenHelper {

    public static final String CREATE_TABLE = "create table person (name text, age integer)";

    public SqlDbHelper(Context context, String name, CursorFactory factory,
            int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建表格
         db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
        // TODO Auto-generated method stub

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}

调用获取SQLiteDatabase

 SqlDbHelper dbHelper = new SqlDbHelper(this, "test.db", null, 1);
        //输入密码加密
        db = dbHelper.getWritableDatabase("123456");

测试代码:

package com.huang.sqlcipher;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;
import android.app.Activity;
import android.content.ContentValues;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity implements OnClickListener{
      private SQLiteDatabase db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        SqlDbHelper dbHelper = new SqlDbHelper(this, "test.db", null, 1);
        //这里的123456是给数据库加密的密码,密码在第一次生效,后期无法修改,当密码为空时,相当于没有加密的数据库
        db = dbHelper.getWritableDatabase("123456");

        //插入数据
        findViewById(R.id.add_data).setOnClickListener(this);
        //查询数据
        findViewById(R.id.query_data).setOnClickListener(this);
        //手机没有root,拷贝数据库到sd卡,看是否加密成功
        findViewById(R.id.copy_db).setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.add_data:
             ContentValues values = new ContentValues();
             values.put("name", "小红");
             values.put("age", 123);
             db.insert("person", null, values);
            break;
        case R.id.query_data:
             Cursor cursor = db.query("person", null, null, null, null, null, null);
             if (cursor != null) {
                 while (cursor.moveToNext()) {
                     String name = cursor.getString(cursor.getColumnIndex("name"));
                     int age = cursor.getInt(cursor.getColumnIndex("age"));
                     Log.d("TAG", "name is " + name);
                     Log.d("TAG", "age is " + age);
                 }
             }
             cursor.close();
            break;
        case R.id.copy_db:
            //找到文件的路径  /data/data/包名/databases/数据库名称
            File dbFile = new File(Environment.getDataDirectory().getAbsolutePath()+"/data/"+getPackageName()+"/databases/test.db");
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                //文件复制到sd卡中
                fis = new FileInputStream(dbFile);
                fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/copy.db");
                int len = 0;
                byte[] buffer = new byte[2048];
                while(-1!=(len=fis.read(buffer))){
                    fos.write(buffer, 0, len);
                }
                fos.flush();

            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                //关闭数据流
                try{
                    if(fos!=null)fos.close();
                    if (fis!=null)fis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }

            }
            break;
        }
    }

}

测试结果:

将db文件拷贝出来并用SQLiteExpertPers打开会出错:

sqlcipher可能存在版本不兼容问题,用最新的jar与so打不以前加密的db文件情况。

源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值