Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
Cómo usar una base SQLite cifrada
Propósito. Proteger datos sensibles en el disco con una base cifrada (vía SQLite3MC). El cifrado es opt-in: sin clave la base es un SQLite común, sin costo de cifrado. Con clave, CrossFly aplica el cifrado y valida la clave en la apertura (falla temprano, no en la primera consulta).
APIs usadas
SqliteDb.open(String filename, byte[] key)— abre/crea cifrado con el cifrado por defectoSqlite.Cipher.CHACHA20(ChaCha20-Poly1305).SqliteDb.open(String filename, byte[] key, Sqlite.Cipher cipher)— abre con cifrado explícito. Opciones:CHACHA20,SQLCIPHER(AES-256-CBC + HMAC),AES128CBC,AES256CBC,RC4,ASCON128.SqliteDb.rekey(byte[] newKey)— cambia la clave víasqlite3_rekey. Pasarnullo un array vacío (new byte[0]) quita el cifrado (“rekey to no key”).SqliteException.code— código numérico del error. Compare con constantes deSqlite. Clave incorrecta / el archivo no es una base ⇒code == Sqlite.NOTADB(26). Otras útiles:Sqlite.BUSY(5),Sqlite.CONSTRAINT(19).
Cómo aparece la clave incorrecta. En el
opencon clave, CrossFly selecciona el cifrado, aplica la clave y hace una lectura forzada (SELECT count(*) FROM sqlite_master) para fallar inmediatamente con clave incorrecta, cerrando la conexión. Usted capturaSqliteExceptionconcode == Sqlite.NOTADB.
Cuidado con el cifrado al reabrir. Para reabrir una base existente, use el mismo cifrado con el que fue creada.
CHACHA20(por defecto) solo descifra basesCHACHA20; una baseSQLCIPHERnecesitaopen(file, key, Sqlite.Cipher.SQLCIPHER).
Ejemplo completo (copiar, pegar y ejecutar)
package com.exemplo;
import java.nio.charset.StandardCharsets;
import dev.crossfly.ui.*; // Window
import dev.crossfly.ui.layout.*; // VerticalLayout
import dev.crossfly.sqlite.*; // SqliteDb, Sqlite, SqliteException
/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
byte[] key = "minha-senha-forte".getBytes(StandardCharsets.UTF_8);
// Abrir/crear cifrado (cifra por defecto CHACHA20)
try (SqliteDb db = SqliteDb.open("secure.db", key))
{
db.exec("CREATE TABLE IF NOT EXISTS secret(id INTEGER PRIMARY KEY, v TEXT)");
db.execute("INSERT INTO secret(v) VALUES(?)", "dado sensível");
// Cambiar la clave
byte[] novaKey = "senha-ainda-mais-forte".getBytes(StandardCharsets.UTF_8);
db.rekey(novaKey);
// db.rekey(new byte[0]); // <- removería el cifrado
}
// Cifra explícita (compatible con SQLCipher)
try (SqliteDb db = SqliteDb.open("sqlcipher.db", key, Sqlite.Cipher.SQLCIPHER))
{
db.exec("SELECT count(*) FROM sqlite_master");
}
// Detectar clave errada
try (SqliteDb db = SqliteDb.open("secure.db", "chave-errada".getBytes(StandardCharsets.UTF_8)))
{
// no llega aquí: la validación ya falló en el open
}
catch (SqliteException e)
{
if (e.code == Sqlite.NOTADB) // 26 = clave errada / no es una base de datos
System.out.println("Chave incorreta");
else
throw e;
}
}
}
El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colóquelo en el esqueleto
MainWindowde arriba.
Fragmento mínimo
// verificado en la fuente: open(file,key), open(file,key,cipher), rekey, SqliteException.code == Sqlite.NOTADB
import dev.crossfly.sqlite.*;
import java.nio.charset.StandardCharsets;
byte[] key = "minha-senha-forte".getBytes(StandardCharsets.UTF_8);
// Abrir/crear cifrado (cifra por defecto CHACHA20)
try (SqliteDb db = SqliteDb.open("secure.db", key))
{
db.exec("CREATE TABLE IF NOT EXISTS secret(id INTEGER PRIMARY KEY, v TEXT)");
db.execute("INSERT INTO secret(v) VALUES(?)", "dado sensível");
// Cambiar la clave
byte[] novaKey = "senha-ainda-mais-forte".getBytes(StandardCharsets.UTF_8);
db.rekey(novaKey);
// db.rekey(new byte[0]); // <- removería el cifrado
}
// Cifra explícita (compatible con SQLCipher)
try (SqliteDb db = SqliteDb.open("sqlcipher.db", key, Sqlite.Cipher.SQLCIPHER))
{
db.exec("SELECT count(*) FROM sqlite_master");
}
// Detectar clave errada
try (SqliteDb db = SqliteDb.open("secure.db", "chave-errada".getBytes(StandardCharsets.UTF_8)))
{
// no llega aquí: la validación ya falló en el open
}
catch (SqliteException e)
{
if (e.code == Sqlite.NOTADB) // 26 = clave errada / no es una base de datos
System.out.println("Chave incorreta");
else
throw e;
}
Profundice
- Buenas prácticas de seguridad · Guía de storage SQLite
- Recetas hermanas: Abrir/crear base · CRUD parametrizado