API reference › @evolu/sqlite-wasm › createEncryptedSqliteDatabase
function createEncryptedSqliteDatabase(
options: SqliteEncryptedFileDatabaseOptions,
): Task<
SqliteEncryptedDatabase,
SqliteVfsIoError | SqliteError,
SqliteWasmDep & SubtleCryptoDep
>;
Defined in: packages/sqlite-wasm/src/Database.ts:1639
Opens an EncryptedFile database on a pool, falling back to the key
@evolu/sqlite-wasm 2.2.4 derived.
@evolu/web passed 2.2.4 the key as the SQL text x'<hex>', SQLCipher's
notation for a raw key, which SQLite3 Multiple Ciphers 2.2.4 treated as a
passphrase because of a bug
(https://github.com/utelle/SQLite3MultipleCiphers/issues/218, fixed in
2.2.5). So every database it encrypted is keyed with PBKDF2-HMAC-SHA512 of
that text, not with the key itself. This Task:
- Opens with the raw key. A new or empty file always accepts it.
- Only when a wrong key failed it, so page 1, or any page while the database has a journal, failed to authenticate, which the codec records as a SqlitePageAuthenticationError, reads the salts through SahPool.read: the file's first 16 bytes, the unencrypted cipher salt, and, when they differ, the first 16 bytes of the first page-1 record the rollback of its hot journal reaches, which stores the salt unencrypted, for a database whose first bytes a crash tore. Another page that fails to authenticate is damaged, because page 1 proved the key, so the open fails with SQLITE_CORRUPT. A database shorter than 16 bytes has no salt, and the raw key's error is returned.
- For each salt, derives the legacy key with deriveLegacySqliteKey, opens again with it as the raw key, and zeroes it, until an open does not fail with a wrong key.
The result says which key opened the database. When no key opens it, the error is the raw key's, unless a later open failed otherwise. Rekeying a legacy database to the raw key is a separate decision: it rewrites every page, needs space, and makes the database unreadable to 2.2.4 tabs that share the pool. Tabs of earlier builds can share the pool in DELETE journal mode only, as this module's documentation describes.