sqlcipher / android-database-sqlcipher

Android SQLite API based on SQLCipher
https://www.zetetic.net/sqlcipher/sqlcipher-for-android/
Other
2.73k stars 564 forks source link

Can't encrypt Database #194

Closed safarious closed 8 years ago

safarious commented 8 years ago

Hello I'm facing following problem. On the launch of the App I create a random Password from SecureRandom. The key has a length of 128bit and looks like following: 41qwvJ1KdljERXPAwzQfug== . The Key is stored in the SharedPreference of my App.

I'll create/use the SQLDatabase like that: SQLiteDatabase mDatabase = new DatabaseHelper(mContext).getWritableDatabase(mKeySaver.getKey());.

If I use the Database for the first time everything works fine. When I close the App and like to use the Database again the app crashes with following Error: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: create locale table failed

I already checked if the Password is the same (and yes it is the same one) - I do not get why this not working... I also tested following: SQLiteDatabase mDatabase = new DatabaseHelper(mContext).getWritableDatabase("TEST"); - This is working fine.

What is the problem here and is there a keyspace for the SQLDatabase Password?

Kind Regards, safarious

developernotes commented 8 years ago

Hi @safarious

Are you able to pull the database off the device/emulator and open the database with your supplied key using the SQLCipher command line tool?

safarious commented 8 years ago

Hi @developernotes I just pulled of the database from my device and tried to open it with the SQLiteManager -> which told me the key is incorrect...

PS: Where can I find the SQLCipher command line tool for mac?

developernotes commented 8 years ago

Hi @safarious

We have instructions available for building it from source here, alternatively if you use Homebrew you can install the shell from there as well, the formula is called sqlcipher.

safarious commented 8 years ago

Hey @developernotes

Thank you. I just installed sqlcipher, I did following: sqlcipher ivocoreDB.db PRAGMA key = 'keEPM0t6X8y6Op0AY7+rIA=='; <-- This is the Key I generated and used to crypt my db ATTACH DATABASE 'plaintext.db' AS plaintext KEY '';

I got following error: Error: file is encrypted or is not a database

What I understand is that the key isn't correct, but I don't get why because that's the one I used to crypt it. Any Ideas?.

developernotes commented 8 years ago

Hi @safarious

Can you post the exact code you are using to both generate and store the key?

safarious commented 8 years ago

Hey @developernotes

Sure here you go:

This is used for generating the key

public static SecretKey generateKey() throws NoSuchAlgorithmException {
        // Generate a 128-bit key
        final int outputKeyLength = 128;
        SecureRandom mSecureRandom = new SecureRandom();
        KeyGenerator mKeyGenerator = KeyGenerator.getInstance("AES");
        mKeyGenerator.init(outputKeyLength, mSecureRandom);
        SecretKey key = mKeyGenerator.generateKey();
        return key;
    }

This is how I set/get the key

    private final String KeyStore = "ivocore.keystore";
    private final String KeyStorePassword = "keystore.password";

public boolean setKey(SecretKey key){
        mSharedPrefs = mContext.getSharedPreferences(KeyStore, Context.MODE_PRIVATE);
        mEditor = mSharedPrefs.edit();
        mEditor.putString(KeyStorePassword, Base64.encodeToString(key.getEncoded(), Base64.DEFAULT));
        mEditor.apply();
        Log.d("KeySaver setKey", "Gespeicherter Schlüssel: " + mSharedPrefs.getString(KeyStorePassword, "Kein Schlüssel"));
        return mSharedPrefs.contains(KeyStorePassword);
    }

    public String getKey(){
        mSharedPrefs = mContext.getSharedPreferences(KeyStore, Context.MODE_PRIVATE);
        Log.d("KeySaver getKey", "Gespeicherter Schlüssel: " + mSharedPrefs.getString(KeyStorePassword, "Kein Schlüssel"));
        return mSharedPrefs.getString(KeyStorePassword, "");
    }
safarious commented 8 years ago

@developernotes I just wanted to ask if you found a solution yet? Kind Regards safarious

developernotes commented 8 years ago

Hello @safarious

I have not had the opportunity to debug your issue at this time. If you could prepare a reproducible unit test within the SQLCipher for Android test suite that replicates your issue I would be happy to look into it further.

sjlombardo commented 8 years ago

@safarious What version of SQLCipher for Android are you running in your project? You can check this using "PRAGMA cipher_version". It is possible that you are using an older version of SQLCipher in your android project than in the shell.

safarious commented 8 years ago

Hi @sjlombardo I've just checked the "PRAGMA cipher_version" it tell's me: 3.3.0.

Hi @developernotes Alright I will do that as soon as possible. I found a new issue in the testing-suite, in several classes is referenced to import net.sqlcipher.DatabaseErrorHandler; which is not in the net.sqlcipher lib.

safarious commented 8 years ago

@developernotes I've wrote a new test for the SQLCipher test suite.

But I'm not able to reproduce the issue, because the test suite clears the database-directory on every launch. However I've attached you the file, I hope it helps. You can find it here!

developernotes commented 8 years ago

Hello @safarious

Please consider forking the test suite and creating the test within the suite, if you bundle the database within the assets directory that will be a good starting place for debugging your scenario. Thank you.

safarious commented 8 years ago

Hi @developernotes Allright you'll find the test-suite here.

Too reproduce the issue do following steps:

  1. Start Test-Suite (Test should Pass)
  2. Kill the Test-Suite
  3. Start the Test-Suite again (Test should Fail)

Kind Regards, safari

safarious commented 8 years ago

Hello @developernotes do you had time yet to look into that problem? Kind Regards, safarious

developernotes commented 8 years ago

Hello @safarious

I haven't had the opportunity to look into this any further yet. Are you using the community edition of SQLCipher for Android, or do you have a commercial license?

safarious commented 8 years ago

Hello @developernotes we're using the community edition of SQLCipher at the moment. Kind Regards