2014-08-30 122 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/