Security implication of using raw binary key

Database can be opened in 2 ways: by passing a passphrase and a raw binary key.

With passphrase, there is key derivation involved and according to documentation, this step is deliberately slow as a security measure against dictionary attack.

My question is if raw binary key is used, is there any security implication? is it more vulnerable to attack compared to using passphrase?

and a related question: if one is using passphrase, is it possible to switch to using raw key? assuming one knows the generated salt and knows how to derive the passphrase with the expected number of iteration.


Hello @rsarma - This is not a straightforward question to answer. The security implications of such a decision will depend entirely on the source of the key material, how it’s stored, and other application-specific factors. To understand what I mean, consider that SQLCipher’s use of key derivation is intended to strengthen keys that might be provided by a user, e.g. passphrases, in two ways:

  1. Slowing down brute force attacks by making it more expensive to try large numbers of passphrases
  2. Protecting against dictionary / table / precomputation by incorporating a salt that is different on every database

In this context it is assumed that the passphrase (starting key material) is potentially at least partially memorable to the user (i.e. is not random) and has substantially less entropy than a 256 bits. Thus, it is important to strengthen the actual encryption key through key derivation to help guard against the aforementioned risks.

On the other hand, SQLCipher’s raw key mode is intended for situations where the application is going to do all the key handling itself. If an application uses a CSRNG generated raw key then there is no need to incur the cost of key derivation: it is already infeasible to directly attack a random key of this size. A random key is theoretically provides the best security, far better than SQLCipher’s key derivation applied to a non-random input.

However, consider an alternate implementation where an application, instead of generating a random key, takes a password from the user as UTF-8 and zero-pads it to 32 byes, then uses that for the raw key. This would be terrible from a security standpoint.

In addition, one challenge with using a purely random raw key is that the user can’t remember it, so it usually needs to be stored somewhere. The application could generate a secure random key but if it is stored unencrypted in some application preference or hardcoded into the application code the implementation will be insecure. Security might be adequate if the random key were stored in a Secure Enclave (i.e. on iOS) though.

The other reason for the raw key mode is if an application wants to handle its own key derivation in some other way. For instance, a custom application could use bcrypt, scrypt, argon2, offload to a hardware security module, combine key material from difference sources, etc. In each of these cases the application can use the raw key feature.

As we’ve remarked before key management is a pretty nuanced subject, subject to tradeoffs and application requirements, but hopefully this provides some guidance on what factors come into play here.

Two answer your second question, it is possible to switch to a raw key instead of a passphrase. The application can do the key derivation internally and then apply the results. Alternately it is possible to change the key either via rekey or sqlcipher_export.