[API reference](https://evolu.dev/docs/api-reference) › [@evolu/sqlite-wasm](https://evolu.dev/docs/api-reference/sqlite-wasm) › createEncryptedSqliteDatabase

```ts
function createEncryptedSqliteDatabase(
  options: SqliteEncryptedFileDatabaseOptions,
): Task<
  SqliteEncryptedDatabase,
  SqliteVfsIoError | SqliteError,
  SqliteWasmDep & SubtleCryptoDep
>;
```

Defined in: [packages/sqlite-wasm/src/Database.ts:1639](https://github.com/evoluhq/evolu/blob/bc4578a260dd15d5bbf94b83765ca05984d194cb/packages/sqlite-wasm/src/Database.ts#L1639)

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:

1. Opens with the raw key. A new or empty file always accepts it.
2. 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](https://evolu.dev/docs/api-reference/sqlite-wasm/interfaces/SqlitePageAuthenticationError), reads the salts through
   [SahPool.read](https://evolu.dev/docs/api-reference/sqlite-wasm/interfaces/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.
3. For each salt, derives the legacy key with [deriveLegacySqliteKey](https://evolu.dev/docs/api-reference/sqlite-wasm/functions/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.