Transparent Full Database SQLite Encryption
SQLCipher is an open source SQLite encryption extension. It provides transparent, full database, AES-256 encryption with minimal performance impact. SQLCipher works by encrypting database pages before they are written to storage and decrypts them on read so encryption functionality is completely separate from the application.
SQLCipher uses good security practices including CBC mode, randomized initialization vectors, and PBKDF2 key derivation with a unique database salt. SQLCipher depends on the trusted and peer-reviewed OpenSSL project for cryptographic functions. SQLCipher is cross platform and has been used successfully on the iPhone, Mac OS X, Linux, and Windows.
About SQLCipher
SQLCipher provides you with a fully-encrypted SQLite database. It’s fast, especially with transactions and indexes, with as little as a 5% performance impact for many common operations. We use SQLCipher as the encrypted database layer for two iPhone applications, Strip and Codebook. If you are using SQLCipher in your own software, let us know, and we’ll list it here. SQLCipher is distributed under a BSD-style license.
How it Works
SQLCipher is an extension to the source SQLite database platform. It takes advantage of the internal SQLite Codec API which allows a callback to be inserted into the pager system that can operate on database pages immediately before they are written to and read from storage. This allows SQLCipher to intercept pages and either encrypt or decrypt them on demand. SQLCipher will ensure that the entire SQLite database is encrypted transparently and on-the-fly, by which we mean:
- Transparent – An application doesn’t require any special knowledge of the underlying database security. An application will use the standard SQLite API to manipulate tables using SQL. Behind the scenes the library silently manages the security aspects.
- On-the-fly – SQLCipher encrypts and decrypts pages as needed in chunks called pages. It doesn’t encrypt or decrypt the database as a whole so it work well and starts up quickly, even with very large databases. This approach also works well with SQLite indexing -for instance retrieving a single record using an indexed search can incur as little as 5% overhead above a standard SQLite database.
SQLCipher does not attempt to implement its own encryption library or cryptographic functions. Instead it uses the widely available and peer-reviewed OpenSSL libcrypto for all cryptographic functions. The following is a short list of the security details:
- The default algorithm is 256-bit AES in CBC mode. The cipher and mode can be changed at run time via “PRAGMA cipher”.
- Each database page is 1024 bytes and is encrypted and decrypted individually. Every page has it’s own initialization vector generated by OpenSSL’s RAND_pseudo_bytes and is stored at the end of the page.
- SQLCipher is often initialized using a passphrase. This password is converted into key data using PBKDF2 (OpenSSL’s PKCS5_PBKDF2_HMAC_SHA1). Each database is initialized with a unique pseduo-random salt in the first 16 bytes of the file. This salt is used for key derivation and it ensures that even if two databases are created using the same password will not have the same encryption key. The default configuration uses 4000 iterations for key derivation, but this can be changed at runtime using “PRAGMA kdf_iter”
- If use of a passphrase is undesirable an application can provide raw binary key data
- When encrypted the entire database file appears to contain random data
Application Interface
To specify an encryption passphrase for the database you can use a pragma. The passphrase you enter is converted to a key using PBKDF2 key derivation and the result is used as the encryption key for the database.
PRAGMA key = ‘passphrase’;Alternately, you can specify an exact byte sequence using a blob literal. If you
use this method it is your responsibility to ensure that the data you provide a
64 character hex string, which will be converted directly to 32 bytes (256 bits) of
key data.
To re-key a database, the PRAGMA rekey is implemented:
PRAGMA rekey = ‘newpassphrase’;To encrypt a database programatically you can use the sqlite3_key function. 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);
PRAGMA key or sqlite3_key should be called as the first operation when a database is open.
Development and Supported Platforms
We recently published a detailed tutorial on Mobile Orchard describing how SQLCipher can be built with XCode and used in iPhone applications. However, SQLCipher has also been used on Mac OS X, Windows, and Linux, and should be usable on any platform that supports SQLite and OpenSSL.
Building
Building SQLCipher is almost the same as compiling a regular version of SQLite with two small exceptions:
- You must define SQLITE_HAS_CODEC
- You need to link against a reasonably modern OpenSSL libcrypto. We’ve tested on tested on 0.9.7 and 0.9.8, but should work on earlier versions too).
Compiling with static linking: (replace /opt/local/lib with the path to libcrypto.a)
./configure CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="/opt/local/lib/libcrypto.a"
make
Compiling with dynamic linking:
./configure CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto"
make
Support
SQLCipher is hosted on Github.
- Bugs: should be filed on the GitHub Issue tracker.
- Questions: should be posted to the SQLCipher Users mailing list.
- Updates: will be posted to SQLCipher Users and our blog.
Note: Due to the amount of email we receive, we ask that you post questions to the SQLCipher Users mailing list instead of contacting us directly.
