10

I am using SQLCipher for Android. I have done all the necessary things that are needed for loading the libs as mentioned in http://sqlcipher.net/sqlcipher-for-android/

I observed that you set the password i.e the key in :

    SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "test123", null);

Then how is your password safe from a hacker? As it can be accessed from a java file. ?

Is there any correct way where i can store the password ?

Thanks, Nibs

user2234
  • 1,282
  • 1
  • 21
  • 44
  • 2
    You could "hide it in plain sight": what if you used a password which is undistinguishable from a color string? i.e.: "#fad005"... or it could be similar to an id, i.e.: "0x7f070005"... Just an idea – Phantômaxx Feb 24 '14 at 12:03
  • @ArtooDetoo: can you please explain more in detail. I am not still clear about it. Thanks – user2234 Feb 24 '14 at 12:05
  • You can use a password string which can easily confound a hacker. He sees strings which represent colors, he's used to see them. But he doesn't know that one of these "colors" is your password. Or you could hide it in your strings.xml,like if it was a normal string, say **2.00.48 r 15** - Just another idea – Phantômaxx Feb 24 '14 at 12:07
  • 1
    @ArtooDetoo: Thanks ArtooDetoo for help. Will try it out :) – user2234 Feb 24 '14 at 16:53
  • 1
    See, these are just simple ideas... you could hide a string into the ARGB components of some custom colors, for example... Or even into a png (this technique is called "Steganography"). – Phantômaxx Feb 24 '14 at 16:55

3 Answers3

4

Then how is your password safe from a hacker?

It's not. Hard-coding a passphrase makes for simple demonstrations, though.

Is there any correct way where i can store the password ?

The user should supply the passphrase for the user's database via your UI. The user then stores the passphrase in the user's head, or perhaps you combine what's in the user's head with something else for lightweight two-factor authentication (e.g., MAC address of paired Bluetooth wearable).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I dont want to take any input from the UI for the password. I want to store a key that would be used for encryption. – user2234 Feb 24 '14 at 16:56
  • 2
    @Nibs: Since anyone who wants to can get to that stored key, what's the point of the encryption? If they can get to the database, they can get to the key. – CommonsWare Feb 24 '14 at 17:06
  • I read this on the link http://sqlcipher.net/design/ When initialized with a passphrase SQLCipher derives the key data using PBKDF2 (OpenSSL’s PKCS5_PBKDF2_HMAC_SHA1). Each database is initialized with a unique random salt in the first 16 bytes of the file. This salt is used for key derivation and it ensures that even if two databases are created using the same password, they will not have the same encryption key. The default configuration uses 64000 iterations for key derivation (this can be changed at runtime using “PRAGMA kdf_iter”). So i guess its ok to keep the password in .java file – user2234 Feb 24 '14 at 18:06
  • 4
    @Nibs: Keeping the password in the Java file means that anyone who wants to can get the password. What you are describing is to prevent brute force attacks when the attacker *doesn't* know the password. – CommonsWare Feb 24 '14 at 19:02
4

I would like to suggest the following approach:

  • The first time you create the database you have to create a random password.
  • You store this password in the Keystore.
  • Whenever you open the app you read the password from the keystore and use it for connecting to the database.

So how does the keystore access work? See blog entry 1 and blog entry 2 and the corresponding github repository. The solution is available for Android version 2.1 to 4.3.

Big caveats:

  1. The solution works only with private API access, so it might break in the future.
  2. A screen lock password is required to store keys and all keys are wiped if a user removes his lock screen password.
Community
  • 1
  • 1
ChrLipp
  • 15,526
  • 10
  • 75
  • 107
1

What is being overlooked is the fact that the demonstration given by SQLCipher is purely for demonstration . It is up to the imagination of the developer to overcome the obvious. Slightly less obvious is that you would NOT store the key in a private local variable, since performing a strings search against your class files could reveal your key, reducing the dictionary necessary in a successful brute force attack. Open your classes.dex in a hex editor and try it.

It isn't the .java files you should be concerned with, as only your developers should be in there. It's the .class files. The next level of effort is some effort of obfuscation, but that really only limits the impatient.

Take a look at this discussion https://groups.google.com/forum/#!topic/sqlcipher/OkE0rUwXEb8

Dan Davis
  • 524
  • 5
  • 9