我正在尝试加密我的数据库并使用this帖子的答案将其保存到sdCard。
但问题是当我将文件放回我的应用包中的databases
文件夹时,
它不能被SQLiteOpenHelper
读取。错误:
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 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();
}
}
答案 0 :(得分:2)
decrypt
方法从inputStream
而不是错误的cipherOutputStream
读取。所以你只是制作副本而不是解密数据库。
答案 1 :(得分:0)
For Encrypting sql database in android please kindly use SQLCipher open library,
follow this simple steps to change existing database to CipherDB.
更改
import android.database.sqlite.SQLiteDatabase;
To
import net.sqlcipher.database.SQLiteDatabase;
更改
OpenHelper cipherHelper = new OpenHelper(Context); SQLiteHelper.sdb = cipherHelper.getWritableDatabase();
To
OpenHelper cipherHelper = new OpenHelper(Context); SQLiteHelper.sdb = cipherHelper.getWritableDatabase(encryptionPassword);
注意:请在运行前卸载旧应用程序。
来源链接: https://www.zetetic.net/sqlcipher/sqlcipher-for-android/