android - 使用 AES 解密 SQLite 数据库

标签 android sqlite encryption

我正在尝试使用 this 的答案加密我的数据库并将其保存到 sdCard邮政 。 但问题是当我将文件放回我的应用程序包中的 databases 文件夹时, SQLiteOpenHelper 无法读取它。错误:

  • 08-30 10:58:35.692: E/SQLiteLog(3801): (26) file is encrypted or is not a database

  • 08-30 10:58:35.692: E/DefaultDatabaseErrorHandler(3801): Corruption reported by sqlite on database: /data/data/com.padra_tech.karamad/databases/PrimaryInformation

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

这是我的课:

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();

}
}

最佳答案

decrypt 方法从 inputStream 而不是错误命名的 cipherOutputStream 读取。因此,您只是制作了一个副本,而不是解密数据库。

关于android - 使用 AES 解密 SQLite 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25579941/

相关文章:

sqlite - Mono.Data.Sqlite.dll 与 SQLite.Net 的兼容性

amazon-web-services - AWS Lambda 是否加密进行中的请求?

java - 尝试将 admob 合并到我的 android 应用程序时出错

java - 如何以编程方式查看 EditText 是否具有日期输入类型?

android - SQLite数据库:- Activity unable to start activity info

android - Bluetooth LE Android 平板电脑无法与 Lego Boost Move Hub 连接

c++ - 如何在我的 C++ 应用程序中编译 sqlite3?

android - 如何从sqlite数据库中获取数据并显示在android中的listview中

security - 验证并签署 HTTP 请求

c# - 解密TripleDES "Bad Data"