2014-08-30 117 views
1

我想加密我的數據庫並將其保存到SD卡使用this後的回答。 但問題是,當我將文件放回我的應用程序包中的databases文件夾中時, 無法通過SQLiteOpenHelper讀取該文件。錯誤:SQLite數據庫解密使用AES

  • 08-30 10:58:35.692:E/SQLiteLog(3801):(26)文件進行加密或不是數據庫

  • 08-30 10點58 :35.692:E/DefaultDatabaseErrorHandler(3801):sqlite在數據庫上報告的損壞:/data/data/com.padra_tech.karamad/databases/PrimaryInformation

  • 08-30 10:58:35.692:E/DefaultDatabaseErrorHandler(3801) :!@ make .back文件

,這是我的課:

package dataBases; 


public class BackupHelper { 

public static int SECURITY_NONE = 1 ; 
public static int SECURITY_ENCRYPTED = 2 ; 

public static void backup(Context context, int securityMode) { 

    File backup = new File(Environment.getExternalStorageDirectory()+ 
      "/" + "KarAmad" + "/" + "backup"); 
    backup.mkdirs(); 

    List<File> src = new ArrayList<File>(); 
    List<File> dst = new ArrayList<File>(); 


    try { 
     src.add(new File(new PrimaryInformationDataBase(context).getDirectory())); 
     dst.add(new File(backup.getPath() + "/" + "PI")); 

     src.add(new File(new TransactionDataBase(context).getDirectory())); 
     dst.add(new File(backup.getPath() + "/" + "T")); 

     src.add(new File(new NoteDataBase(context).getDirectory())); 
     dst.add(new File(backup.getPath() + "/" + "N")); 

     src.add(new File(new PictureDataBase(context).getDirectory())); 
     dst.add(new File(backup.getPath() + "/" + "P")); 

     for(int i = 0 ; i < src.size() ; i ++) { 
      dst.get(i).createNewFile(); 
      if(securityMode == SECURITY_ENCRYPTED) 
       BackupHelper.encrypt(src.get(i), dst.get(i)); 
      else 
       LeftFragment.copy(src.get(i), dst.get(i)); 
     } 

     Toast.makeText(context, "پشتیبان گیری انجام شد", Toast.LENGTH_SHORT).show(); 

    } catch (Exception e) { 

     Toast.makeText(context, "پشتیبان گیری انجام نشد!", Toast.LENGTH_SHORT).show(); 
     e.printStackTrace(); 

    } 
} 

public static void restore(Context context, int securityMode) { 

    NoteDataBase dummyNoteDataBase = new NoteDataBase(context); 
    String temp = dummyNoteDataBase.getDirectory(); 
    String dataBasesPath = temp.substring(0, temp.lastIndexOf("/")); 

    File source = new File(Environment.getExternalStorageDirectory()+ 
      "/" + "KarAmad" + "/" + "backup"); 

    List<File> src = new ArrayList<File>(); 
    List<File> dst = new ArrayList<File>(); 

    try { 
     src.add(new File(source.getPath() + "/" + "PI")); 
     dst.add(new File(dataBasesPath + "/" + "PrimaryInformation")); 

     src.add(new File(source.getPath() + "/" + "T")); 
     dst.add(new File(dataBasesPath + "/" + "Transaction")); 

     src.add(new File(source.getPath() + "/" + "N")); 
     dst.add(new File(dataBasesPath + "/" + "Note")); 

     src.add(new File(source.getPath() + "/" + "P")); 
     dst.add(new File(dataBasesPath + "/" + "Picture")); 

     for(int i = 0 ; i < src.size() ; i++) { 

      dst.get(i).createNewFile(); 

      if(securityMode == SECURITY_ENCRYPTED) 
       BackupHelper.decrypt(src.get(i), dst.get(i)); 
      else 
       LeftFragment.copy(src.get(i), dst.get(i)); 
     } 



     Toast.makeText(context, "بازیابی فایل پشتیبان انجام شد", Toast.LENGTH_SHORT).show(); 

    } catch (Exception e) { 

     Toast.makeText(context, "بازیابی فایل پشتیبان انجام نشد!", Toast.LENGTH_SHORT).show(); 
     e.printStackTrace(); 

    } 
} 

public static void encrypt(File src, File dst) throws IOException, 
    NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 

    FileInputStream inputStream = new FileInputStream(src); 
    FileOutputStream outputStream = new FileOutputStream(dst); 

    SecretKeySpec keySpec = new SecretKeySpec("1393032613930326".getBytes(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, keySpec); 

    CipherOutputStream cipherOutputStream = 
      new CipherOutputStream(outputStream, cipher); 

    int b; 
    byte[] d = new byte[8]; 
    while((b = inputStream.read(d)) > 0) { 
     cipherOutputStream.write(d, 0, b); 
    } 

    cipherOutputStream.flush(); 
    cipherOutputStream.close(); 
    inputStream.close(); 
} 


public static void decrypt(File src, File dst) throws IOException, 
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 

    FileInputStream inputStream = new FileInputStream(src); 
    FileOutputStream outputStream = new FileOutputStream(dst); 

    SecretKeySpec keySpec = new SecretKeySpec("1393032613930326".getBytes(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, keySpec); 

    CipherInputStream cipherOutputStream = 
      new CipherInputStream(inputStream, cipher); 

    int b; 
    byte[] d = new byte[8]; 
    while((b = inputStream.read(d)) > 0) { 
     outputStream.write(d, 0, b); 
    } 

    outputStream.flush(); 
    outputStream.close(); 
    cipherOutputStream.close(); 

} 
} 
+0

您使用的是相同的代碼後?如果不是,你可以提供你使用的代碼片段加密和解密數據庫 – hoomi 2014-08-30 07:18:26

+0

@hoomi我添加了代碼 – Mohsen 2014-08-30 07:27:03

+0

我只是想知道。你想加密目錄或文件嗎? – hoomi 2014-08-30 07:33:48

回答

2

decrypt方法從inputStream,而不是名不副實cipherOutputStream讀取。所以你只是做一個副本而不是解密數據庫。

+0

非常感謝 – Mohsen 2014-08-30 08:04:06

0
For Encrypting sql database in android please kindly use SQLCipher open library, 
follow this simple steps to change existing database to CipherDB. 

enter image description here

  • 變化

    進口android.database.sqlite.SQLiteDatabase;

        To 
    

    import net.sqlcipher.database.SQLiteDatabase;

  • 變化

    OpenHelper cipherHelper =新OpenHelper(上下文); SQLiteHelper.sdb = cipherHelper.getWritableDatabase();

        To 
    

    OpenHelper cipherHelper = new OpenHelper(Context); SQLiteHelper.sdb = cipherHelper.getWritableDatabase(encryptionPassword);

    注意:請在運行前卸載舊的應用程序。

來源鏈接: https://www.zetetic.net/sqlcipher/sqlcipher-for-android/