How to store the key used in SQLCipher for android
Asked Answered
S

3

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

Sash answered 24/2, 2014 at 12:0 Comment(5)
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 ideaPaulapauldron
@ArtooDetoo: can you please explain more in detail. I am not still clear about it. ThanksSash
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 <string name="app_ver">2.00.48 r 15</string> - Just another ideaPaulapauldron
@ArtooDetoo: Thanks ArtooDetoo for help. Will try it out :)Sash
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").Paulapauldron
S
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).

Shimkus answered 24/2, 2014 at 12:3 Comment(4)
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.Sash
@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.Shimkus
I read this on the link 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 fileSash
@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.Shimkus
K
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.
Karikaria answered 20/8, 2014 at 15:17 Comment(0)
S
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

Shuman answered 21/8, 2014 at 23:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.