SQLCipher android 數據庫加密

amyna 8年前發布 | 14K 次閱讀 數據庫 安卓開發 Android開發 移動開發

補充的問題

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader
[DexPathList[[zip file "/data/app/org.xiaozhi-2/base.apk"],
nativeLibraryDirectories
=[/data/app/org.xiaozhi-2/lib/arm64,
 /data/app/org.xiaozhi-2/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]]
 couldn't find "libsqlcipher.so"

這是我本身項目的目錄結構.png

解決的方法:

將我之前 所有的compile 改成了compile file lib 目錄下 只保留armeabi平臺的 不分各種cpu 選擇

//數據庫加密 
//compile 'net.zetetic:android-database-sqlcipher:3.5.3@aar'
compile files('libs/sqlcipher.jar')
// xutils  
//compile 'org.xutils:xutils:3.3.36'
compile files('libs/xutils3.3.36.jar')

項目中引入了SQLCipher之后,會讓你的程序體積驟然增加,打成APK后大概會變大好幾M,是更側重于文件大小,還是更側重于程序安全,你應該根據具體的需求做出合適的判斷。

  • manifest 配置寫入文件權限 因為copy的數據庫文件到創建的目錄下
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • module 下的build.gradle
    compile 'net.zetetic:android-database-sqlcipher:3.5.3@aar'
  • 混淆
    -dontwarn net.sqlcipher.**
    -keep class net.sqlcipher.** {*;}
  • application 或者你當前所用到的activity 首先要加上這句話
    SQLiteDatabase.loadLibs(this);
  • 創建一個MyDatabaseHelper
    public class MyDatabaseHelper extends SQLiteOpenHelper {     
    public static final String CREATE_TABLE = "create table Book(name text, pages integer)";  
    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);    }    
    @Override    
    public void onCreate(SQLiteDatabase db) {        db.execSQL(CREATE_TABLE);    }    
    @Override   
    public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {    }}
  • 關鍵代碼 activity
public class MainActivity extends AppCompatActivity {

private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

//因為很多手機沒有root 過 所以你沒辦法去找到你的db文件 并且copy出來查看 這時候需要手動去創建目錄
createSdcardFolder(); setContentView(R.layout.main); SQLiteDatabase.loadLibs(this); MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "cipher.db", null, 1); db = dbHelper.getWritableDatabase("secret_key"); Button addData = (Button) findViewById(R.id.add_data); Button queryData = (Button) findViewById(R.id.query_data); addData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ContentValues values = new ContentValues(); values.put("name", "達芬奇密碼"); values.put("pages", 566); db.insert("Book", null, values); } }); queryData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Cursor cursor = db.query("Book", null, null, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); int pages = cursor.getInt(cursor.getColumnIndex("pages")); Log.d("TAG", "book name is " + name); Log.d("TAG", "book pages is " + pages); } } cursor.close(); } }); //copy出數據庫文件 copyfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { copyDatabaseToSdcard(MainActivity.this); } }); } / 創建SdcardFolder / public void createSdcardFolder(){ if(SDCardUtils.isSDCardEnable()){ File file =null; file = new File(String.format("%s%s",SDCardUtils.getSDCardPath(), "/cliper/temp")); if(!file.exists()){//判斷sdcard卡上是否有目錄,沒有目錄則生成目錄 file.mkdirs(); } } } / 復制數據庫文件 / public static void copyDatabaseToSdcard(Context context){ copyDatabaseToSdcard(context,"dbfile"); } / 復制數據庫文件 / public static void copyDatabaseToSdcard(Context context,String name){ try { File file = context.getDatabasePath("cipher.db"); FileUtil.writeFile(new FileInputStream(file.getAbsolutePath()), SDCardUtils.getSDCardPath() +"/cipher/temp" + "/"+name); } catch (IOException e) { e.printStackTrace(); } } }</code></pre>

  • 數據庫加密之后 用工具無法打開。這就足以說明,目前數據庫中的數據是非常安全的,只有在應用程序里通過SQLCipher提供的API才可以訪問到數據庫里的數據,使用其它的方式都無法獲取其數據。

DCC53C0C-0FA4-4386-BB8D-F3DFBF916E1D.png

  • 創建目錄

    /

    • 創建SdcardFolder */

      public void createSdcardFolder(){ if(SDCardUtils.isSDCardEnable()){

       File file =null;
       file = new File(String.format("%s%s",SDCardUtils.getSDCardPath(), "/cipher/temp"));
       if(!file.exists()){
           file.mkdirs();
       }
      

      } }</code></pre> </li>

    • SDCardUtils

      public static String getSDCardPath(){
      return Environment.getExternalStorageDirectory().toString();
      }
    • FileUtil
      public final static void writeFile(InputStream input, String fileName) throws IOException {
       writeFile(input, new FileOutputStream(fileName));
      }
      public final static void writeFile(InputStream input, OutputStream os) throws IOException
      {  
      byte[] bs = new byte[1024];  // 設置數據緩沖  
       int len;   // 讀取到的數據長度 
       while ((len = input.read(bs)) != -1) {   
      os.write(bs, 0, len);   }  
      os.close();  
      input.close();
      }
      我自己經歷的錯誤 :
      1.你首先要確信 你的手機里 沒有你現在建好的db 文件 否則它會告訴你不能加密此文件 :

      error.jpg

    • </ul>

      2.我在as里 使用了 eclipse 配置的方法 卻沒有在build.gradle文件里做配置 eclipse的配置這些so 文件 jar包 zip 文件 都要有

      sourceSets {
         main {
             manifest.srcFile 'src/main/AndroidManifest.xml'
             java.srcDirs = ['src/main/java']
             res.srcDirs = ['src/main/res']
             assets.srcDirs = ['assets']
             jniLibs.srcDirs = ['libs']
         }
      }

      注意這些文件都要有.png

       

      來自:http://www.jianshu.com/p/485cb2a6989e

       

 本文由用戶 amyna 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!