Java 为SQLCipher加密已存在的数据库
我在我的应用程序中使用已经存在的数据库(另请参见)。我用Java应用程序加密了数据库。 在我的应用程序中,我尝试用以下代码读取加密的_数据库,但我得到了一个SQLiteException:文件已加密或不是数据库:Java 为SQLCipher加密已存在的数据库,java,android,database,encryption,sqlcipher,Java,Android,Database,Encryption,Sqlcipher,我在我的应用程序中使用已经存在的数据库(另请参见)。我用Java应用程序加密了数据库。 在我的应用程序中,我尝试用以下代码读取加密的_数据库,但我得到了一个SQLiteException:文件已加密或不是数据库: SQLiteDatabase.loadLibs(mContext); SQLiteDatabase dataBase = SQLiteDatabase.openDatabase(mPath, mPassword, null, SQLiteDatabase.OPEN_RE
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和现有数据库的问题是,我必须将完整的未加密的_数据库复制到加密的_数据库。这需要很长时间,当我在我的手机上这样做
我的想法是:用java编写一个加密数据库的应用程序,并在应用程序中使用这个加密的_数据库。其结果是,我只需在我的应用程序中打开已存在的加密_数据库,无需复制
现在我编写了一个Java应用程序(基于),但仍然存在一些与SQLCipher及其设计()相关的问题:
- 如何在数据库页面中划分数据库?在数据库中,页面仅由其大小(1024字节)定义。但我必须在加密的_数据库文件中写入什么来表示“数据库页面开始”或“数据库页面结束”
- salt和随机初始化向量(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(); }
我非常感谢每一个帮助/想法/评论:)不建议尝试从头开始重新创建SQLCipher文件。该格式比您正在做的更复杂,并且复制一个有效的SQLCipher文件非常重要。相反,您应该只使用to进行分发。谢谢您的回答。我看到了SQLCipherAPI,但不知道如何解决我的问题。你的回答让我有了一个想法:)。下次我会试试的。