2

I'm trying to create DB using sqlcipher and then access it by using hex value of password key. According to description from github (https://github.com/sjlombardo/sqlcipher) key is hashed by sha256 algorithm and then used to cipher DB. There is a choice to provide the key in plain and hex form through PRAGMA directive. And if I use plain version it all works correctly, but I unable to access DB with hex key value. For example in my case key is 'demo' and when I use PRAGMA key='demo' all works. I got sha256 with:

echo -n demo | shasum -a256 2a97516c354b68848cdbd8f54a226a0a55b21ed138e207ad6c5cbb9c00aa5aea

and then provided it to PRAGMA directive according to instructions in sqlite3_exec call:

sqlite3_exec(db, "PRAGMA key = x'2a97516c354b68848cdbd8f54a226a0a55b21ed138e207ad6c5cbb9c00aa5aea'", NULL, NULL, NULL);

but this doesn't work.

What is the hex value of key should I provide to PRAGMA directive?

MPelletier
  • 16,256
  • 15
  • 86
  • 137
user478681
  • 8,330
  • 4
  • 26
  • 34

1 Answers1

3

The results of pragma key when passed a text value vs a raw hex value are not interchangeable.

  • If you provide a text key via PRAGMA key='demo', SQLCipher uses PBKDF2 to derive the key data (see http://sqlcipher.net/design). This uses a random per-database salt and 4000 iterations by default.
  • If you provide a hex key then SQLCipher uses the binary value as the key directly with no derivation.

Thus, the actual encryption key will be quite different beween the two modes you mentioned. If you are not sure which to use, you should probably default to using the first method, as the key derivation step provides a greater level of protection against brute force and dictionary attacks.

I'll try to update the readme in the future to make this more clear.

Stephen Lombardo
  • 1,503
  • 8
  • 7
  • So um... how do you set the key from the PRAGMA interface when the key contains unprintable characters? It doesn't seem to work if I force weird binary valued characters in between quotes, even if I make sure to double up single quotes. – Michael Feb 05 '17 at 05:08
  • Also, if I try the opposite way, calling sqlite3_key and then issuing `PRAGMA kbd_iter=0` it doesn't seem to have the same effect say using `PRAGMA key = "x'...'"` – Michael Feb 05 '17 at 05:09
  • If you are using binary data as the key material, you can either: 1) If the data is random, use the hex key syntax, providing a full set of key material. It will not be run through key derivation 2) If the data is binary but not random, encoded it, i.e. Base 64 or hex, etc, and then pass it in as a string, at which point it will be run through key derivation. – Stephen Lombardo Feb 06 '17 at 13:34
  • It's unclear to me how to pass a raw key to the sqlite3_key interface, as all signs seem to point to it being equivalent to the non-raw PRAGMA – Michael Dec 06 '18 at 22:36
  • @Michael Oh, do you just pass a literal string "x'<64 byte hex string>'" to sqlite3_key? I was assuming some way of passing a raw binary buffer of 32 bytes I guess... – Michael Dec 06 '18 at 22:43
  • @Michael correct, the value passed to sqlite3_key or sqlite3_key_v2 will be the same as you would provide to PRAGMA key. The main difference between a standard key and a raw hex key is that in the latter key derivation is not applied. – Stephen Lombardo Dec 07 '18 at 12:51