SQLCipher: SQLite with a codec compiled in, and a passphrase that is really a PBKDF2 input
SQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files and other security features.
At a glance
- What is it?
- SQLCipher is a standalone fork of SQLite maintained by Zetetic that encrypts the whole database file with 256 bit AES. Building it takes four extra defines and a crypto provider, and the format is only interchangeable within one major version.
- Who is it for?
- Adopt SQLCipher when the database file itself has to be unreadable on disk, because that is the whole design and the overhead is quoted at 5 to 15 percent on many operations. Plan the upgrade path before you ship, because format compatibility holds only within a major version and moving from 3.x to 4.x means migrating databases or enabling a backwards-compatibility mode.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- sqlcipher/sqlcipher7,329 ★ · +49
| Repository | 2026-09-23 | 2026-11-14 |
|---|---|---|
| sqlcipher/sqlcipher | 7.3k | 7.3k |
49 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A build needs four extra defines and a crypto provider, and a partial build is the dangerous case
SQLCipher is a standalone fork of the SQLite database library, maintained by Zetetic, that adds 256 bit AES encryption of database files plus on-the-fly encryption, tamper detection, memory sanitization and strong key derivation. It is written in C, licensed BSD-3-Clause, and the README notes that the project minimizes alterations to core SQLite code whenever possible, and that stable upstream release features are periodically integrated.
Building is described as similar to compiling a regular version of SQLite from source, with a few small exceptions. You must define SQLITE_HAS_CODEC, define SQLITE_TEMP_STORE=2 or 3 or use configure's --with-tempstore=yes option, define SQLITE_EXTRA_INIT=sqlcipher_extra_init and SQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown, define SQLITE_THREADSAFE to 1 or 2 which configure enables automatically, and compile and link with a supported cryptographic provider.
The supported providers are OpenSSL, LibTomCrypt, CommonCrypto with Security.framework, and NSS. The README's examples all use OpenSSL, described as readily available on most Unix-like systems, and note that in the example --with-tempstore=yes sets SQLITE_TEMP_STORE=2 while SQLITE_THREADSAFE defaults to 1.
$ ./configure --with-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown" \
LDFLAGS="-lcrypto"
$ makeThe reason to enumerate all four defines rather than say run configure is that they are independent.
A passphrase goes through PBKDF2, and the hex form hands you the raw key instead
To specify an encryption passphrase through the SQL interface you use a PRAGMA, and the passphrase is passed through PBKDF2 key derivation to obtain the encryption key for the database:
PRAGMA key = 'passphrase';Alternately you can specify an exact byte sequence using a blob literal, and the README is explicit about the cost: it is your responsibility to ensure the data you provide is a 64 character hex string, which is converted directly to 32 bytes of key data without key derivation.
PRAGMA key = "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";So the two forms differ by more than syntax. The string form derives a key from a passphrase, which means a weak passphrase produces a weak key and PBKDF2's iteration cost buys you something. The hex form is the key itself, which means every bit of its security is in the 64 characters and there is no derivation to slow an attacker down.
Programmatic callers use the sqlite3_key function, and the data provided in pKey is converted to an encryption key according to the same rules as PRAGMA key:
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);One ordering rule applies to all three: PRAGMA key or sqlite3_key should be called as the first operation when a database is open. Anything you read or write before that call is operating on a database the codec has not yet unlocked.
To rotate a passphrase on an existing database you supply the current one and then rekey, and there is a hex form of rekey as well for moving to a specific binary value:
PRAGMA key = 'passphrase'; -- start with the existing database passphrase
PRAGMA rekey = 'new-passphrase'; -- rekey will reencrypt with the new passphraseFormat compatibility stops at the major version, and 3.x to 4.x is a real migration
The compatibility statement is precise about its limits. SQLCipher maintains database format compatibility within the same major version number, so an application on any platform can open databases created by any other application provided the major version is the same between them.
Across major versions that guarantee ends. Major version updates often include changes to default settings, and newer major versions will not open databases created by older versions without using special settings. SQLCipher 4 is given as the concrete example: it introduces many new performance and security enhancements, and the new default algorithms, increased KDF iterations and larger page size mean it will not open databases created by SQLCipher 1.x, 2.x or 3.x by default.
An application facing that upgrade has two options, per the README: migrate the older databases to use the new format, or enable a special backwards-compatibility mode. The available options are described in the upgrade documentation on the project's discussion forum.
Two consequences follow for planning. First, a mixed fleet is only safe within one major version, so if several applications share databases, their SQLCipher versions have to move together. Second, the compatibility mode is not free: it exists because the new defaults are better, and turning it on means running with the old algorithms or the old page size, which is the tradeoff you would only make to postpone a migration.
The security practices listed are CBC mode, HMAC and key derivation, and 100% of data in the database file is encrypted. The overhead figure the README gives is as little as 5-15% for encryption on many operations, which is the number to benchmark against your own workload rather than assume.
With no key it is plain SQLite, and that is also how you encrypt an existing file
SQLCipher is also compatible with standard SQLite databases. When a key is not provided, SQLCipher behaves just like the standard SQLite library.
That sentence has two quite different implications depending on which side you are on. For an application that never sets a key, it means the library is a drop-in SQLite replacement and the database is not encrypted. For an application migrating an existing plaintext database, it means the file is readable by any SQLite tool until you convert it.
The conversion path is named explicitly: it is possible to convert from a plaintext database to an encrypted SQLCipher database using ATTACH and the sqlcipher_export() convenience function. The mechanism is that you open the plaintext database, attach the target as an encrypted database with its own key, and export into it. The project documentation links a forum thread on doing this while avoiding the file is encrypted or is not a database errors, which is the failure you get when a tool opens an encrypted file without supplying a key.
That error is worth anticipating in your own tooling. Any component in your stack that opens the file with a stock SQLite library, a backup script that copies and reads, or a GUI database browser, will report that the file is encrypted or is not a database, so every reader in your stack needs the key, including the ones nobody remembers are readers.
The SQLite test suite is expected to fail, and testfixture is what replaces it
The README states plainly that the full SQLite test suite will not complete successfully when using SQLCipher. In some cases encryption interferes with low-level tests that require access to database file data or features which are unsupported by SQLCipher, and tests intended to support encryption are meant for non-SQLCipher implementations. There is a second reason: because SQLite tests are not always isolated, one failure can trigger a domino effect with failures in later steps.
So the project ships its own. The SQLCipher package includes independent tests that exercise and verify the core functionality of the SQLCipher extensions, intended as an abbreviated verification of SQLCipher's internal logic. The README is careful about what that suite is not: it does not perform an exhaustive test of the SQLite database system as a whole, and it does not verify functionality on specific platforms.
The reasoning behind that limit is worth stating, because it tells you what the suite is relying on. Because SQLCipher is based on stable upstream builds of SQLite, it is considered a basic assumption that the core SQLite library code is operating properly, the SQLite core being almost untouched in SQLCipher. The SQLCipher-specific tests provide the verification that the library operates as expected with its security features enabled.
Running them needs SQLCIPHER_TEST defined alongside the usual defines, plus --enable-fts5, and then the testfixture target:
$ ./configure --with-tempstore=yes --enable-fts5 CFLAGS="-DSQLITE_HAS_CODEC -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown -DSQLCIPHER_TEST" \
LDFLAGS="-lcrypto"
$ make testfixture
$ ./testfixture test/sqlcipher.testIf you vendor SQLCipher into a distribution, that configure line and the testfixture run are the closest thing the project offers to a pass criterion.
Contributions target the prerelease branch under an agreement, and 5.0.0 is currently a beta
Two things about how the project takes changes are stated in the README and both are easy to miss.
The first is the branch. All contributions including pull requests and patches should be based on the prerelease branch, not master. The default branch of the repository is master, so the branch you see is not the branch you should target.
The second is the contributor agreement, which the README says must accompany every contribution, and it strongly encourages discussion of the proposed change prior to development and submission. The discussion venue is a forum on the Zetetic site, split into a category for SQLCipher.
The release history explains why the prerelease branch matters right now. The three most recent tags are v4.20.0 on the same day as the last push, v5.0.0-beta.1 five days earlier, and v5.0.0-beta on 2026-09-15. A 5.0.0 beta means the next major version is in open testing, and by the compatibility rule above, anything you build against it may not read 4.x files by default, since major version updates often change default settings.
That makes this a bad moment to bind a production deployment to the head of the tree. The defensible choices are to track the 4.x line, which is what the stable tags describe, or to take 5.0.0-beta knowingly and accept that it is still a beta. The repository is not archived, the last push was 2026-10-27, and the project also publishes a man page, a pkg-config template in sqlite3.pc.in and platform directories including macosx/ and contrib/, which is the layout of a source tree meant to be compiled rather than consumed as a library package.
Editorial conclusion
Adopt SQLCipher when the database file itself has to be unreadable on disk, because that is the whole design and the overhead is quoted at 5 to 15 percent on many operations. Plan the upgrade path before you ship, because format compatibility holds only within a major version and moving from 3.x to 4.x means migrating databases or enabling a backwards-compatibility mode. Pass the passphrase as a string and let PBKDF2 run, and treat the raw hex key form as a liability rather than a convenience, since it removes key derivation and makes the 64 character string the entire secret. And if you build from source, define all the required macros and link a supported provider.
Frequently asked questions
What is SQLCipher?
SQLCipher is a standalone fork of the SQLite database library that adds 256 bit AES encryption of database files, plus on-the-fly encryption, tamper detection, memory sanitization and strong key derivation. It is written in C, licensed BSD-3-Clause and maintained by Zetetic, LLC. The README states that 100% of data in the database file is encrypted, with as little as 5-15% overhead for encryption on many operations.
What is the difference between SQLite and SQLCipher?
SQLCipher is based on SQLite and integrates stable upstream release features periodically, while minimizing alterations to core SQLite code. When a key is not provided, SQLCipher behaves just like the standard SQLite library. The differences appear once you set a key: the file becomes unreadable without it, and the codec adds tamper detection, memory sanitization and key derivation on top of AES encryption.
Is SQLCipher free for commercial use?
The repository is licensed BSD-3-Clause, with LICENSE.md and LICENSE.txt in the tree alongside SQLITE_LICENSE.md for the upstream SQLite code it derives from. Contributions are a separate matter: the README requires every pull request and patch to be accompanied by a contributor agreement, and to be based on the prerelease branch rather than master.
How to unlock a locked SQLite database?
Supply the passphrase as the first operation after opening the database, using PRAGMA key = 'passphrase'; which runs the passphrase through PBKDF2 key derivation, or the sqlite3_key function, which follows the same conversion rules. To change the passphrase on a database you already have open, supply the current one with PRAGMA key and then issue PRAGMA rekey with the new value, which reencrypts the file.
how to install sqlcipher
The repository ships the standard SQLite build machinery, so installation is compiling from source: run ./configure with -DSQLITE_HAS_CODEC, the SQLITE_EXTRA_INIT and SQLITE_EXTRA_SHUTDOWN defines for sqlcipher_extra_init and sqlcipher_extra_shutdown, and --with-tempstore=yes, then link a supported cryptographic provider. The supported providers named in the README are OpenSSL, LibTomCrypt, CommonCrypto with Security.framework, and NSS.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/sqlcipher-sqlcipher)Star history chart for your README
[](https://hysenlabs.com/projects/sqlcipher-sqlcipher)Was this useful?