By design, SQLCipher doesn’t perform permanent storage of the database password and key material. This provides maximum flexibility, allowing an application to provide key material from any combination of sources (e.g. user provided passphrase, key material on device, external hardware tokens, etc.).
While this cleanly separates the management of the key material from the implementation of the database encryption, allowing SQLCipher to address the widest possible set of requirements and use cases, it also means the integrating application is responsible for key management.
Application key management is a deep and interesting topic, subject to many security tradeoffs, and highly dependent on the application design and the security requirements. That said, we universally recommend that:
- At least a substantial part of the key material for SQLCipher databases should come directly from the user, and should not be stored on the device itself (i.e. a passphrase).
- The key material should not be hard coded into an application.
In other words, it would be fine to take a passphrase from a user and mix in some material like a random file or device ID into the key, provided that a significant part of the key material is a secret coming directly from the user when the application runs.
Note that hardcoding a key in application code is not suitable for any secure implementation. While a hardcoded key may provide rudimentary DRM functionality for simple applications, as long as the key is in the binary, a dedicated attacker will be able to find it and use it to compromise a database.
Note that storing key material on the device is also risky, even when using a system Keychain or a permission-secured file. In these cases physical compromise of a device could effectively render the encryption useless if the the key material is stored in an accessible place.