SQLCipher Support for Database Encryption
SQLite.swift provides first-class support for SQLCipher, an open-source extension to SQLite that provides transparent 256-bit AES encryption of database files.
Installation
To use SQLCipher, you must install SQLite.swift using the SQLCipher
CocoaPods subspec. This automatically includes the SQLCipher pod and enables the encryption-specific extensions.
In your Podfile
:
target 'YourAppTargetName' do
# Make sure you only require the subspec. Do not add the base 'SQLite.swift' pod.
pod 'SQLite.swift/SQLCipher', '~> 0.15.4'
end
Then run pod install
.
Encrypting a New Database
To create a new encrypted database, simply open a connection and provide a key using the key()
method immediately after.
import SQLite
let db = try Connection("path/to/encrypted.sqlite3")
try db.key("a-very-secret-password")
// The database is now encrypted. All subsequent operations are transparently encrypted/decrypted.
try db.run("CREATE TABLE secrets (id INTEGER PRIMARY KEY, data TEXT)")
Opening an Existing Encrypted Database
To open an existing encrypted database, you follow the same process: connect, then provide the key.
let db = try Connection("path/to/encrypted.sqlite3")
try db.key("a-very-secret-password")
// If the key is correct, you can now access the data.
let count = try db.scalar("SELECT count(*) FROM secrets")
If the key is incorrect, the key()
method (or a subsequent database operation) will throw an error, typically with the result code SQLITE_NOTADB
.
Changing the Encryption Key
To change the key of an already encrypted database, use the rekey()
method. The database must first be unlocked with the current key.
let db = try Connection("path/to/encrypted.sqlite3")
// 1. Unlock with the old key
try db.key("a-very-secret-password")
// 2. Set the new key
try db.rekey("a-new-and-better-password")
Encrypting an Existing Plaintext Database
To encrypt a database that was not previously encrypted, you can use the sqlcipher_export()
function. This attaches a new encrypted database and copies the content over.
let unencryptedDB = try Connection("path/to/unencrypted.sqlite3")
// Export the contents to a new, encrypted database
try unencryptedDB.sqlcipher_export(.uri("encrypted.sqlite3"), key: "a-very-secret-password")