我在我的应用程序中使用已存在的数据库(另请参阅1)。我用Java Application加密了数据库。 在我的应用程序中,我尝试使用以下代码读取encrypted_database,但我得到 SQLiteException:文件已加密或不是数据库:
SQLiteDatabase.loadLibs(mContext);
SQLiteDatabase dataBase = SQLiteDatabase.openDatabase(mPath, mPassword, null, SQLiteDatabase.OPEN_READONLY);
String query = "Select distinct _id from TABLE";
Cursor cursor = dataBase.rawQuery(query, null);
return cursor;
我已经使用SQLCipher加密了我的数据库,我也可以读取数据,所以一切正常。
SQLCipher和现有数据库的问题是我必须将完整的unencrypted_database复制到encrypted_database。我在手机上执行此操作需要很长时间。
我的想法是:在java中编写一个应用程序,用于加密数据库并在您的应用程序中使用此encrypted_database。这导致我只需在我的应用程序中打开已存在的encrypted_database,并且不需要复制。
现在我编写了一个Java应用程序(基于2,3),但仍有一些与SQLCipher及其设计相关的问题(4):
是盐和随机初始化向量(iv)的1024字节的一部分吗?
public static void main(String[] args) throws Exception{
outFile_enc = new FileOutputStream(mFileNameEncrypted);
outFile_dec = new FileOutputStream(mFileNameDecrypted);
int keyLength = 256;
// salt
salt = new byte[16];
Random rnd = new Random();
rnd.nextBytes(salt);
int iterations = 4000;
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(mPassWord.toCharArray(), salt, iterations, keyLength);
SecretKey passwordKey = keyFactory.generateSecret(keySpec);
key = new SecretKeySpec(passwordKey.getEncoded(), "AES");
// creates a cipher and init it for encryption
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
AlgorithmParameters params = cipher.getParameters();
iv = params.getParameterSpec(IvParameterSpec.class).getIV();
encryptData(cipher);
}
public static void encryptData(Cipher cipher) throws Exception{
// File to encrypt
inFile = new FileInputStream(mFileName);
// unique random salt in the first 16 bytes of the file
outFile_enc.write(salt);
// Read file and encrypt its bytes
byte[] input = new byte[64];
int bytesRead;
while((bytesRead = inFile.read(input)) != -1){
byte[] output = cipher.update(input, 0, bytesRead);
if(output != null)
outFile_enc.write(output);
}
byte[] output = cipher.doFinal();
if(output != null)
outFile_enc.write(output);
// random initialization vector is stored at the end of a page
outFile_enc.write(iv);
inFile.close();
outFile_enc.flush();
outFile_enc.close();
}
我感谢每一个帮助/想法/评论:)
答案 0 :(得分:2)
不建议尝试从头开始重新创建SQLCipher文件。格式比您正在执行的操作更复杂,并且重要的是重现有效的SQLCipher文件。相反,您应该使用SQLCipher command line program至encrypt your database进行分发。