1. 程式人生 > >Android加密已有的sqlite資料庫---sqlcipher

Android加密已有的sqlite資料庫---sqlcipher

 android中資料庫的加密,通過百度都可以看到,大多都使用的是sqlcipher,好處之一是因為:1.它是開源的,免費的。2.它的運用非常簡單,方便,跟sqlite的操作一樣,只不過是換成了sqlcipher的包而已。

好的,廢話不多說,網上的文章加密資料庫,基本上都是新建一個數據庫,而對已有的資料庫進行加密,卻少之又少。我找了好半天,也才找到下面兩篇,大家可以作為參考。

文章1

文章2

這裡說一下思路:加密已有的sqlite資料庫,其實是對原有的資料庫進行了一份拷貝。只是拷貝後的資料庫有了加密功能。拷貝的話就是拷貝原有資料庫的表或者資料。這裡我選擇拷貝表。

使用流程如下(這裡以AS開發工具為例):

1.新建android工程,在app的build.gradle中加入如下程式碼編譯程式碼:

dependencies {
   compile 'net.zetetic:android-database-sqlcipher:[email protected]'
}

我這裡的sqlcipher版本是3.5.7,具體最新版可以檢視官網

2.等待編譯成功後,便可在MainActivity中新增加密函式,這裡注意,讀取原始資料庫和生成新的加密資料庫不能在外部SD卡中,具體原因我還不知,我也在mainfest.xml中配置了外部讀寫許可權和程式碼中書寫了執行時許可權,也不行。有測試可行或者知道的讀者請告訴我哈。下面給出加密和讀取加密資料庫的函式。還有在讀取資料庫時路徑要取絕對路徑

,如果是自己定義的路徑,會報錯(我這裡ce's)。

1.MainActivity.java

package com.example.**.sqlclipher;

import android.Manifest;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import net.sqlcipher.database.SQLiteDatabase;              //注意匯入的包

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private static final int SUCCESS_ID = 1;
    private static final int FAIL_ID = 0;
    private Button mEncryptButton;
    private Button mDecryptButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          // 該語句必不可少
        SQLiteDatabase.loadLibs(MainActivity.this);

        mEncryptButton = (Button) findViewById(R.id.btn_encry);
        mDecryptButton = (Button) findViewById(R.id.btn_read);
              // 開啟按鈕點選進行加密
        mEncryptButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                 // 開啟一個子執行緒來作為加密的耗時操作
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                     // 這裡傳入新加密後的資料庫名,未加密資料庫名,以及加密的密碼
                        encrypt("cliper.db", "origin.db", "key");
                    }
                });
                thread.start();

            }
        });

        mDecryptButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //這裡因為加密好的資料庫放到了/data/data/包名/files/目錄下,注意這裡取得是絕對路徑
                String path = MainActivity.this.getFilesDir().getAbsolutePath()
                        + File.separator + "encrypted.db";
                readClipherData(path, "key");
            }
        });
    }

    Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case SUCCESS_ID:
                    Toast.makeText(MainActivity.this, "加密成功", Toast.LENGTH_SHORT).show();
                    break;
                case FAIL_ID:
                    Toast.makeText(MainActivity.this, "加密失敗", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

    /**
     * 加密資料庫
     */
    private void encrypt(String encryptedName,String decryptedName,String key) {
        Message msg = new Message();
        try {
            File file = new File(getApplication().getDatabasePath(DATA_PATH + encryptedName).getPath());
             // 新建加密後的資料庫檔案,並設定其密碼key
            SQLiteDatabase dataTarget = SQLiteDatabase.openOrCreateDatabase(MainActivity.this.getFilesDir().getAbsolutePath()
                    + File.separator + encryptedName, key, null);
            String path = File.separator + "data" + File.separator +decryptedName;
             //執行sql語句,連線未加密的資料庫,並將其取別名為sourceLib,因為未加密資料庫沒密碼,所以密碼為""
            dataTarget.execSQL("attach '"+path+"' as sourceLib key '';");
            /*String passwordString = "1234"; //只能對已加密的資料庫修改密碼,且無法直接修改為“”或null的密碼
            database.changePassword(passwordString.toCharArray());*/
             
             // 執行sql語句,在加密後的資料庫檔案中新建表,並將未加密的資料庫表拷貝到新的加密資料庫中,原資料庫有多張表,該操作重複多少次
            dataTarget.execSQL("create table new_table as select * from sourceLib.table");

            //斷開同加密後的資料庫的連線
            dataTarget.execSQL("detach database 'sourceLib'");
            dataTarget.close();
            msg.what = SUCCESS_ID;
        } catch (Exception e) {
            msg.what = FAIL_ID;
            e.printStackTrace();
        }finally {
            mHandler.sendMessage(msg);
        }
    }

    /*
    *讀取加密後的資料
     */

    private void readClipherData(String databasePath, String key){
        try{
            SQLiteDatabase encrypteddatabase = SQLiteDatabase.openOrCreateDatabase(databasePath, key, null);
            String[] columns  = new String[]{
                    "*"
            };
            String sections = "**";     //這裡填寫查詢條件
            Cursor cursor = encrypteddatabase.query("wordings", columns, sections, null, null, null, null);
            if (cursor == null){
                Toast.makeText(MainActivity.this, "未查詢到資料", Toast.LENGTH_SHORT).show();
            }else {
                if (cursor.moveToFirst()) {
                    do {
                        String value = cursor.getString(cursor.getColumnIndexOrThrow("value"));
                        Log.e(TAG, "readClipherData: value = " + value);
                    } while (cursor.moveToNext());
                }
                cursor.close();
            }
            encrypteddatabase.close();
        }catch (Exception e){
            e.printStackTrace();
        }


    }

}



其實縱觀整個加密過程,就是用sqlcipher包含的方法開啟或者建立加密資料庫,然後執行相應的sql語句。

上面只給出了主要的程式碼,查詢應該也放到子執行緒中等寫的不規範,見諒。

相關推薦

Android加密有的sqlite資料庫---sqlcipher

 android中資料庫的加密,通過百度都可以看到,大多都使用的是sqlcipher,好處之一是因為:1.它是開源的,免費的。2.它的運用非常簡單,方便,跟sqlite的操作一樣,只不過是換成了sqlcipher的包而已。 好的,廢話不多說,網上的文章加密資料庫,基本上都是

sqlcipher加密資料庫及其時機

  最近我們做的移動im打算將資料庫加密,我們的資料庫是對資料庫的簡單封裝 ,調研了一些開源資料庫加密工具,覺得sqlcipher使用者會多一點,而且開源。所以打算就用它了   sqlcipher的使用可以參考下這兩篇文章:   http://www.jianshu.com

Android資料儲存之Sqlite採用SQLCipher資料庫加密實戰

前言:   最近研究了Android Sqlite資料庫(文章地址:http://www.cnblogs.com/whoislcj/p/5506294.html)以及ContentProvider程式間資料共享(http://www.cnblogs.com/whoislcj/p/5507928.html),

Android 資料儲存之 SQLite資料庫儲存

轉載自:https://www.cnblogs.com/woider/p/5136734.html ----------------------------------------SQLite資料庫---------------------------------------------- SQLite是一

Android 第三章 SQLite 資料庫

1,使用execSQL API 操作資料庫。      步驟1,建立Class MyOpenHelper實現介面SQLiteOpenHelper,複寫建構函式、onCreate、onUpgrade方法;      步驟2,在建立MyOpenHelper物件myOpenHelp

JIN學習一、Android使用C/C++程式碼、第三方SO庫的方法

1.配置好NDk編譯環境(這個Google一下,:)) 2.將已有C/C++程式碼,編譯成SO檔案 3.Eclipse中新建Android工程,建立一個jni目錄。如下所示 4.在jni目錄建立C/C++檔案,裡面呼叫步驟2函式,或者第三方SO的函式 5.建立Androi

Android使用C/C++程式碼、第三方SO庫的方法(JIN學習)

1.配置好NDk編譯環境(這個Google一下,:)) 2.將已有C/C++程式碼,編譯成SO檔案 3.Eclipse中新建Android工程,建立一個jni目錄。如下所示 4.在jni目錄建立C/C++檔案,裡面呼叫步驟2函式,或者第三方SO的函式 5.建

Android開發案例:SQLite資料庫和ListView列表結合

        SQLite是Android系統內建的輕量級的關係型資料庫,執行速度非常快;ListView是Android中最常用的的控制元件之一,幾乎所有的應用程式都會用到它。本文通過一個例項介紹如何通過ListView列表展示資料以及實現SQLite資料庫的增刪改查,

android學習之通過sqlite資料庫實現記事本

最近學習了資料庫,於是寫了一個記事本來體驗了一下資料庫因為最近的事情比較多,所以介面或者有些設計不是那麼完美,但是作為一個可擴充套件的筆記本demo也已經是足夠了,這個例子實現的是,可以註冊多個使用者,然後每個使用者都對應有一個記事本記錄,ok,程式碼: package c

Android開發 SQLite 通過.db檔案匯入資料庫

那,如果想要用一個已有的資料庫怎麼辦? 因為Android系統下的資料庫是存放在/data/data/com.*.*(package name)/目錄下,所以我們可以這樣:1.將.db檔案放到專案原始碼的res/raw目錄下; 2.用FileInputStream讀取原資料; 3.用FileOutPutSt

Android 中 匯入存在的 sqlite資料庫時出現的問題

1》剛開始時我匯入sqlite資料庫放在了asserts下面,我按照網上的例子最後發現是我的“包名”出了問題,我現在用Android studio 以前用的時eclipse  ,所以習慣性的我就應用了mainfaset下面的包名了,所以不管我怎麼讀取sqlite檔案總是打不開

Android訪問存在的SQLite資料庫

上篇文章講的是用DatabaseHelper新建一個數據庫再進行增刪改查,但大多數情景是資料庫已經存在了,那怎麼去訪問呢?思路是先判斷data/data/<package_name>/databases目錄下資料庫是否存在,如果不存在,用流操作把res/raw或

Django Sqlite 資料庫,在表中新增新欄位

Django 使用預設的 sqlite 資料庫,想在已經建立的表中新增一個新的欄位,操作很簡單。 1、直接在你要新增新欄位的app的 models.py 檔案中新增,如下: # -*- coding

Sqlcipher給現有的SQLite資料庫加密

android專案資原始檔的破譯非常簡單,出於安全的考慮,要對sqlite檔案進行加密處理,用到了SQLCipher,他有收費版和開源版,這裡選擇開源版。 PS:網上的Sqlcipher版本大多是需要編譯的版本,使用起來非常不方便,這裡推薦一款windows下

C++編譯SQLite資料庫以及如何使用加密資料庫SQLCipher

一、前言最近在倒騰東西的時候無意中需要在PC端解密某社交工具的資料庫,移動裝置中的加密資料庫資訊

android 加密手機完畢後待機兩分鐘出現頻率的雜音

加密 tin ger 詳細 pps 主動 oid per 手機 這個音效是code裏面主動加的,是為了提醒end user輸入PIN的一個提示音,也標誌著加密手機動作的完畢。 詳細位置是在alps\packages\apps\Settings\src\com\andro

React-Native開發二 Android 專案整合React-Native

1 前言 之前寫過一篇RN的環境搭建教程和新建一個新的RN專案的文章 https://blog.csdn.net/qiyei2009/article/details/78820207 但是其實在實際開發中,在已有的android專案中整合RN情況更普遍,這篇文章就是一個怎麼在已有

資料庫表匯入到powerDesigner生成pdm檔案

如何將資料庫中已有表匯入到powerDesigner生成pdm檔案   1、create new PDM; 2、select database menu; 3、click Reverse  Engin

Android核心技術-day03-01-建立SQLite資料庫

MyDBOpenHelper.java package com.gaozewen.createdb; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.

Python程式設計:peewee的pwiz將資料庫轉為Model

peewee可以用Model直接在資料庫中建立表 反過來也可以,用資料庫中已經存在的表建立Model 前提:已經安裝peewee模組pip install peewee $ python -m pwiz -e mysql -H localhost -p 3306 -u root