The JavaScript/WASM build can be created using a copy of the SQLite Encryption Extension (SEE), but doing so comes with some caveats:
This project does not provide pre-built WASM SEE builds. Users requiring SEE builds will have to create the build themselves (see instructions below). Similarly, there are no npm packages (or similar) for such builds (and the SEE license prohibits such distribution), so clients using SEE will have to do so the old-fashioned way, with vanilla JS and no package manager.
SEE's license is at odds with distribution of SQLite via client-side WASM because WASM deployments effectively provide each client with a full copy of the SEE code. This project's official stance is that it is acceptable for an SEE licensee to host an SEE-capable WASM build within a private/intranet-only application within their organization, but may not host an SEE WASM build on a public-facing site nor to organizations which have themselves not licensed SEE. "Server-side" WASM builds are unaffected by that stance, but this page specifically covers browser-side WASM usage.
Only encryption options which do not require third-party library dependencies can be used here. In short, that means that clients are restricted to the
sqlite3-see.csource file, as opposed to one of the othersqlite3-see-XYZ.cvariants.There is no known way in JavaScript to reliably hide SEE encryption keys. Any user who loads an SEE-capable site can freely inspect the JavaScript code and other assets. The only way to ensure that encryption keys remain secret is to require that end users enter them manually (noting that browser-side password managers will helpfully offer to save them).
Encryption is arguably redundant for the persistent storage options because the underlying data are locked away in browser-specific storage which is illegible even to the browser's user. The argument could be made that anyone with direct access to a given user's login and browser can read the content, but the counter-argument of "physical access trumps all security measures" also applies (and see the above note about password managers). Encryption is unnecessary in the non-persistent storage modes because the databases exist only in memory. SEE specifically does not encrypt in-memory or temporary databases, and the non-persistent storage options are actually in-memory databases which are accessed via (transient) filesystem-like paths.
Creating an SEE-capable WASM Build
Creating an SEE-capable build is identical to the canonical builds
except for one detail: when invoking make we have to tell it which
sqlite3.c to use:
$ make sqlite3.c=/path/to/sqlite3-see.c # needs to be an absolute path
See the canonical builds for info about the various build targets, optimization levels, and descriptions of the build's output files.
Assuming all goes well, the output of the build will start with something like:
$ make
using emcc version [4.0.12]
This is an SEE build.
...
If that "SEE" line (or something equivalent) does not appear, the build is not SEE-capable. It is also possible to inspect the resulting JS sources to determine whether it's an SEE build:
$ grep -w sqlite3_key_v2 jswasm/sqlite3.js
If that produces any output then the resulting build is SEE-capable.
When alternating between SEE- and non-SEE builds it is necessary to
run make distclean between each build, followed by re-running
configure from the top of the tree, to ensure that the version
information which gets baked into the JS files is pulled from the
proper copy of sqlite3.c.
Using the SEE Build
The SEE build is used identically to the main distribution, but also
includes the various sqlite3 API functions related to encryption, such
as sqlite3_key_v2(). Those functions are not required for using
encryption, as each such API is also accessible via pragmas, as
documented in the SEE docs. The existence of the SEE-specific
functions in a JS/WASM build can be used to distinguish it from a
non-SEE build.
As of version 3.46, the oo1 API supports SEE in the
form of an optional argument to the
constructors of the DB class and its
subclasses.