SQLCipher: an encrypted SQLite fork, and what it takes to build it
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 keeps SQLite's file format but encrypts the whole database with 256 bit AES. The catch is the build: you compile it yourself with a specific set of defines and a crypto provider, and major versions do not open each other's files by default.
- Who is it for?
- SQLCipher is for teams that already ship SQLite and need the file on disk to be unreadable without a key, and who are willing to own the build. It is not for anyone who wants a package manager to hand them a working encrypted database, and it is not a fix for a weak passphrase or a key stored next to the file.
- 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 15 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 September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem SQLCipher solves, and who actually needs it
SQLite stores a database as a single file, and that file is plaintext. Anyone who copies it can read every row. SQLCipher is a standalone fork of SQLite that encrypts the whole file with 256 bit AES, so the same file without the key is noise. The README lists on-the-fly encryption, tamper detection, memory sanitization and strong key derivation as the additions, and states that 100% of data in the database file is encrypted.
That framing matters for who this is for. If your threat model is a stolen laptop, a backup that lands in the wrong bucket, or an app sandbox you do not fully trust, file level encryption is the right layer. If your threat model is a determined attacker with code execution on the running process, SQLCipher does not change the picture much, because the key has to be in memory for the database to be usable.
The project is maintained by Zetetic, LLC. It is a fork rather than an extension, which is the central design decision: the README says stable upstream SQLite release features are integrated periodically and that alterations to core SQLite code are minimized. You get SQLite's behaviour and SQLCipher's crypto, but you also inherit the job of tracking two release streams.
How the encryption is wired into the SQLite code path
The mechanism is a codec layer compiled into the library, not a wrapper around it. The README's build instructions require four defines before anything works: SQLITE_HAS_CODEC, SQLITE_TEMP_STORE set to 2 or 3, SQLITE_EXTRA_INIT=sqlcipher_extra_init, and SQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown, plus SQLITE_THREADSAFE at 1 or 2. Those extra init hooks are how the codec registers itself with the SQLite core without patching the core heavily.
At runtime the key is supplied through the SQL interface with a PRAGMA. The README states that PRAGMA key = 'passphrase' runs the passphrase through PBKDF2 key derivation to produce the encryption key. There is a second path: a blob literal of exactly 64 hex characters is converted straight to 32 bytes of key material with no derivation at all. That distinction is easy to miss and it changes your security posture completely, because a raw key has no work factor behind it.
Ordering is a real constraint. The README says PRAGMA key or sqlite3_key should be called as the first operation when a database is open. Call it late and you get the is-not-a-database class of error rather than a helpful message.
For the C API, the entry point is:
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);The README notes the data in pKey follows the same conversion rules as PRAGMA key, so a passphrase and a 64 character hex string take different paths through the same function.
Compiling SQLCipher and encrypting a database step by step
The README does not point at a package manager. It points at the source tree, and the build is SQLite's build with extra flags. The documented OpenSSL example configures with a temp store and passes the codec defines through CFLAGS, linking against libcrypto through LDFLAGS:
$ ./configure --with-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown" \
LDFLAGS="-lcrypto"
$ makeAfter make finishes you have a sqlcipher library and command line tool built from this tree. The README notes that --with-tempstore=yes is what sets SQLITE_TEMP_STORE=2 for the build, and that SQLITE_THREADSAFE defaults to 1, so you do not have to pass it in this configuration.
To verify the build, the README gives a separate test configuration that adds --enable-fts5 and the SQLCIPHER_TEST define, then builds the testfixture binary and runs the project's own test file:
$ ./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.testThe README's SQL interface examples show the key and rekey pragmas, and the hex form of the rekey pragma is mentioned there as the way to rekey to a specific binary value:
PRAGMA key = 'passphrase';
PRAGMA rekey = 'new-passphrase';The README states that rekey reencrypts with the new passphrase, and that the first pragma must supply the existing database passphrase before it. Close the database, reopen it without the PRAGMA key line, and the file will not read as a database. That is the behaviour to look for: the same binary, the same path, a different result depending on whether the key was supplied first.
Where SQLCipher breaks, and the cases it is the wrong tool for
The build is the first limitation and it is not incidental. There is no documented install command for Windows, macOS, Android, iOS or Python in the README. The repository has Makefile.linux-generic, Makefile.msc and make.bat, so platform builds exist in the tree, but the README itself only walks through the autoconf path with OpenSSL. Anyone expecting a drop-in replacement for a system SQLite package will spend their first day on toolchain work.
The second limitation is version compatibility, and it is the one that bites in production. The README is explicit: format compatibility holds within the same major version, and major updates often change default settings. SQLCipher 4 will not open databases created by 1.x, 2.x or 3.x by default, because of new default algorithms, increased KDF iterations and a larger page size. Your options are migrating the old databases or enabling a backwards-compatibility mode, both described in the project's upgrade documentation rather than in the README. If you have field-deployed 3.x files and no migration plan, upgrading the library is a data availability problem, not a dependency bump.
The third limitation is testing. The README states plainly that the full SQLite test suite will not complete successfully when using SQLCipher, because encryption interferes with low-level tests that read file data directly, and because SQLite tests are not always isolated, so one failure can cascade. SQLCipher ships its own suite instead, which the README describes as an abbreviated verification of SQLCipher's internal logic. It does not exhaustively test SQLite as a whole and does not verify specific platforms. If your release process depends on the upstream SQLite suite passing, that process does not survive contact with SQLCipher.
Finally, SQLCipher is not a key management system. It encrypts the file and derives a key from what you give it. Where that passphrase comes from, and whether it sits in a config file next to the database, is outside the library.
SQLCipher versus plain SQLite, and versus application layer encryption
The comparison the project itself invites is with standard SQLite, and the README makes it concrete: when a key is not provided, SQLCipher behaves just like the standard SQLite library. That is the real difference. Same API, same SQL, same file format family, one extra PRAGMA at open time. The cost is the defines, the crypto provider link, and the version pinning described above.
Against application layer encryption, the difference is where the boundary sits. Encrypting individual columns leaves the schema, the row count, the indexes and the query patterns readable in the file. SQLCipher encrypts the whole file, so the structure is not visible either. What you give up is queryability over encrypted data: you cannot index or search a column without decrypting it, because the database cannot see it either. If you need to search ciphertext, SQLCipher is the wrong layer and you want something built for that.
The README also documents a migration path in both directions. Because SQLCipher reads plaintext SQLite when no key is given, you can convert an existing plaintext database to an encrypted one using ATTACH and the sqlcipher_export() convenience function, which the README links to rather than spelling out. The reverse is the same mechanism. That export function is the practical answer to the version migration problem too, since it moves data rather than reinterpreting the file.
Maintenance, releases and the licence you are actually accepting
The repository is not archived, and the last push was on 2026-09-15. The release list shows v4.19.0 on 2026-09-08 and v4.18.0 on 2026-08-18, with v5.0.0-beta on 2026-09-15. A beta in the 5.0 line is worth noting before you plan an upgrade around it: the README's compatibility rules are written per major version, and a major version bump is exactly the event that changes default settings and breaks file opening.
The upgrade cost is the part teams underestimate. Because the codec is compiled in, the library is not something your package manager patches for you. Every platform you ship on needs its own build with the four defines and a crypto provider, and the README names four providers: OpenSSL, LibTomCrypt, CommonCrypto/Security.framework, and NSS. Choosing one per platform, and keeping those choices consistent, is ongoing work rather than a one-time setup.
On licensing, the repository carries BSD-3-Clause, and there are separate LICENSE.md, LICENSE.txt and SQLITE_LICENSE.md files at the top level, which reflects the fork's dual heritage: SQLite's public domain core plus Zetetic's additions. The BSD-3-Clause terms are permissive and place few conditions on redistribution, but the SQLITE_LICENSE.md file exists for a reason and should be read alongside it. That is a description of what the repository contains, not legal advice; if you are shipping a closed product, have counsel read both files rather than a review of this project.
Editorial conclusion
SQLCipher is for teams that already ship SQLite and need the file on disk to be unreadable without a key, and who are willing to own the build. It is not for anyone who wants a package manager to hand them a working encrypted database, and it is not a fix for a weak passphrase or a key stored next to the file. Before committing, verify three things: which major version you are standardising on, because 4.x will not open 1.x, 2.x or 3.x files without special settings; which crypto provider your target platforms can link, since the README names OpenSSL, LibTomCrypt, CommonCrypto and NSS; and whether your existing test suite is the SQLite one, because the README states the full SQLite test suite will not complete successfully under SQLCipher and you are expected to run test/sqlcipher.test instead.
Frequently asked questions
What is SQLCipher?
SQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files, along with tamper detection, memory sanitization and strong key derivation. It is maintained by Zetetic, LLC, and when no key is provided it behaves just like the standard SQLite library.
What is the difference between SQLite and SQLCipher?
SQLite stores the database as a plaintext file; SQLCipher encrypts 100% of the data in that file and adds security features on top of the SQLite core. The API is otherwise the same, with a PRAGMA key or sqlite3_key call required as the first operation when the database is opened.
How do I install SQLCipher?
The README documents building it from source rather than installing a package. You configure with --with-tempstore=yes, pass CFLAGS containing SQLITE_HAS_CODEC, SQLITE_EXTRA_INIT=sqlcipher_extra_init and SQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown, link a supported crypto provider through LDFLAGS, and run make.
How do I use SQLCipher?
Open the database and issue PRAGMA key = 'passphrase' as the first operation, which runs the passphrase through PBKDF2 key derivation. To change it later, supply the existing passphrase with PRAGMA key and then run PRAGMA rekey = 'new-passphrase' to reencrypt.
Is SQLCipher safe?
The README describes the design as CBC mode with HMAC, key derivation and memory sanitization, and states that 100% of the database file is encrypted. It also notes that a blob literal key of 64 hex characters is converted directly to 32 bytes without key derivation, so that path carries no work factor.
Is SQLCipher open source?
Yes. The repository is licensed BSD-3-Clause, with additional LICENSE.md, LICENSE.txt and SQLITE_LICENSE.md files at the top level reflecting the SQLite core it forks.
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)