Skip to content

unable to provide raw key data to sqlcipher #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
abeluck opened this issue Mar 16, 2013 · 8 comments
Closed

unable to provide raw key data to sqlcipher #94

abeluck opened this issue Mar 16, 2013 · 8 comments

Comments

@abeluck
Copy link
Contributor

abeluck commented Mar 16, 2013

SQLCipher supports bypassing the key derivation by passing the raw 256bit AES key directly. (as per example #2)

However, the Android Java API makes this feature impossible to use. Or rather, I haven't quite figured it out :)

The format in which you're supposed to supply the raw key is x'HEX BYTES', however the way in which the Java wrapper passes the key to SQLCipher (here) causes SQL to choke on the single quote characters in the x'foo' construction:

execSQL("PRAGMA key = '" + password + "'");

I've tried various escaping strategies, but to no avail:

E/Database(21936): Failure 1 (unrecognized token: "5c18f7e2a5bbe1ca50abfcb41bc9dedc01355d4755e7d0ad6cedc942f9d89902") on
0x5dd05510 when preparing 'PRAGMA key = 'x\'5c18f7e2a5bbe1ca50abfcb41bc9dedc01355d4755e7d0ad6cedc942f9d89902\'''

Also, I think this might allow for SQL injection.

@illarionov
Copy link
Contributor

I use SQLiteDatabaseHook for that:

SQLiteDatabase db = SQLiteDatabase.openDatabase(path,
  "",
  mFactory,
  flags,
  new SQLiteDatabaseHook() {
     @Override
     public void postKey(SQLiteDatabase arg0) {
        arg0.execSQL("PRAGMA key = \"x'<key>'\"");
        arg0.execSQL("PRAGMA cipher_use_hmac = OFF");
        arg0.execSQL("PRAGMA cipher_page_size = 4096");
     }
     @Override
     public void preKey(SQLiteDatabase arg0) {
     }
  }
);

@abeluck
Copy link
Contributor Author

abeluck commented Mar 16, 2013

Interesting. I suppose the subsequent call to PRAGMA key= after the hook is simply ignored?

IMHO, this is still a workaround though. And I'm still not convinced there isn't a SQL injection here :P

@abeluck
Copy link
Contributor Author

abeluck commented Mar 16, 2013

Alright, I've found an alternative workaround that doesn't make use of hooks. SQL allows you to escape single quotes with another quote character.

So in Java you can form your string like so:

String pass = "x''4f07ef26f41aa3384a861992334fc9c664de810d6ddaaeeb6d59420e0b51cf39''"

I've verified this does indeed skip the key derivation by enabling CODEC_DEBUG and running a unit test:

I/Zetetic (26859): Running test:Raw Key Data Test
I/stdout  (26859): codec_pragma: entered db=0x5d994888 iDb=0 pParse=0x5c259c68 zLeft=key zRight=x'4f07ef26f41aa3384a861992334fc9c664de810d6ddaaeeb6d59420e0b51cf39' ctx=0x0
I/stdout  (26859): sqlite3_key: entered db=0x5d994888 pKey=x'4f07ef26f41aa3384a861992334fc9c664de810d6ddaaeeb6d59420e0b51cf39' nKey=67
I/stdout  (26859): sqlite3CodecAttach: entered nDb=0 zKey=x'4f07ef26f41aa3384a861992334fc9c664de810d6ddaaeeb6d59420e0b51cf39', nKey=67
I/stdout  (26859): sqlcipher_codec_ctx_set_use_hmac: use=1 block_sz=16 md_size=20 reserve=48
I/stdout  (26859): sqlcipher_cipher_ctx_copy: entered target=0x5cbbde28, source=0x5cd16238
I/stdout  (26859): codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=1024 reserve=48
I/stdout  (26859): sqlite3Codec: entered pgno=1, mode=6, page_sz=1024
I/stdout  (26859): codec_key_derive: entered c_ctx->pass=x'4f07ef26f41aa3384a861992334fc9c664de810d6ddaaeeb6d59420e0b51cf39', c_ctx->pass_sz=67                 ctx->kdf_salt=0x5af56fb8 ctx->kdf_salt_sz=16 c_ctx->kdf_iter=4000                 ctx->hmac_kdf_salt=0x5cd12478, c_ctx->fast_kdf_iter=2 c_ctx->key_sz=32
I/stdout  (26859): codec_key_derive: using raw key from hex
I/stdout  (26859): codec_key_derive: deriving hmac key from encryption key using PBKDF2 with 2 iterations
I/stdout  (26859): sqlcipher_cipher_ctx_cmp: entered c1=0x5cbbde28 c2=0x5cd16238

@abeluck
Copy link
Contributor Author

abeluck commented Mar 16, 2013

I'll close this and open another ticket for the SQL injection.

@abeluck abeluck closed this as completed Mar 16, 2013
@git-jeeva
Copy link

If the database is bundled within the apk file, how can I verify if key derivation? Basically I want to verify of the raw key is used from hex.

@developernotes
Copy link
Member

Hello git-jeeva,

Openning a connection via a raw hex key requires that you provide the key in the correct format. Please see the documentation here covering the details of the format.

@git-jeeva
Copy link

Hi,

The previous post stated that "....verified this does indeed skip the key derivation by enabling CODEC_DEBUG..." How is this configuration done to verify the key generation steps?

Thanks, Jeeva

@developernotes
Copy link
Member

Hello @git-jeeva,

CODEC_DEBUG within the build of SQLCipher enables the output of CODEC_TRACE statements within the source. You would need to adjust the CFLAGS within the build, also need to redirect standard out for visibility in logcat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants