SQLite.Encrypted for Cordova and Capacitor
@sqlite-encrypted/cordova retains the cordova-sqlite-storage JavaScript API and replaces its Android and iOS implementations with SQLite.Encrypted. The same plugin is compatible with Capacitor; there is no separate Capacitor package.
Core rule: Wait for
deviceready, activate SEE, then open withkey.
Codec support: SQLite.Encrypted currently supports only
aes256ofb. Pass a null codec to useaes256ofb; any codec supplied tokey()orrekey()must beaes256ofb. Keyed opens use the sameaes256ofbdefault.
Install in Cordova
Configure the SQLite.Encrypted npm scope in the project's .npmrc:
@sqlite-encrypted:registry=https://packages.sourcegear.com/npm/
Then install the plugin:
cordova plugin add @sqlite-encrypted/cordova
cordova prepare
The Cordova plugin ID is sqlite-encrypted-cordova.
Install in Capacitor
npm install @sqlite-encrypted/cordova
npx cap sync
Use a native Android or iOS Capacitor build. Browser, macOS, and Windows implementations are not included.
Activate and open
document.addEventListener('deviceready', async () => {
await new Promise((resolve, reject) => {
window.sqlitePlugin.activateSEE(
activationKey,
resolve,
reject
);
});
const database = window.sqlitePlugin.openDatabase({
name: 'application.db',
location: 'default',
key: databaseKey,
});
});
The keyed open routes through the native key implementation and reports a key-loading failure through the open callback. Omit key for a plaintext database. Opening without key and immediately calling database.key() is the preferred alternative when the key is not available at open time.
Open with PRAGMA
Open without a key, then execute both statements before schema access. Verify that the key PRAGMA returns one row containing ok.
document.addEventListener('deviceready', async () => {
const database = window.sqlitePlugin.openDatabase({
name: 'application.db',
location: 'default',
});
const execute = sql => new Promise((resolve, reject) => {
database.executeSql(sql, [], resolve, reject);
});
await execute("PRAGMA activate_extensions = 'see-<activation-key>'");
const result = await execute("PRAGMA key = '<database-key>'");
const row = result.rows.length ? result.rows.item(0) : null;
if (!row || Object.values(row)[0] !== 'ok') {
throw new Error('SEE did not accept the database key');
}
});
On a build without encryption support, or when SEE cannot load the key, the key PRAGMA returns no row. Ignoring that result can leave the application using a connection whose encryption key was never applied. Prefer keyed open or database.key() for new integrations.
Create and query a table
The ordinary cordova-sqlite-storage database and transaction API is unchanged.
database.transaction((transaction) => {
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS notes (' +
'id INTEGER PRIMARY KEY, body TEXT NOT NULL)'
);
transaction.executeSql(
'INSERT INTO notes(body) VALUES (?)',
['hello']
);
transaction.executeSql(
'SELECT id, body FROM notes ORDER BY id',
[],
(_tx, result) => {
for (let index = 0; index < result.rows.length; index += 1) {
console.log(result.rows.item(index));
}
}
);
});
Text, binary, and null keys
The open database adds callback-based key and rekey methods. The key may be a string, Uint8Array, or null.
const call = (operation) => new Promise((resolve, reject) => {
operation(resolve, reject);
});
await call((ok, fail) =>
database.key(null, 'initial text key', null, ok, fail)
);
const binaryKey = Uint8Array.from([0x01, 0x00, 0x7f, 0xff]);
await call((ok, fail) =>
database.rekey(null, binaryKey, null, ok, fail)
);
await call((ok, fail) =>
database.rekey(null, 'replacement text key', null, ok, fail)
);
await call((ok, fail) =>
database.rekey(null, null, null, ok, fail)
);
Null removes encryption. Null database and codec values select the main database and the aes256ofb default.