SQLite con protección de cifrado / contraseña

136

Estoy aprendiendo a usar SQLite y tenía curiosidad si eso es posible:

  1. Cifrado del archivo de base de datos?

  2. ¿La contraseña protege la apertura de la base de datos?

PD. Sé que existe esta "Extensión de cifrado SQLite (SEE)", pero de acuerdo con la documentación, "El SEE es software con licencia ..." y "El costo de una licencia de código fuente perpetuo para SEE es de US $ 2000".

ahmd0
fuente
Ciertamente es posible y existen varias soluciones de código abierto además de VER. Entre ellos, la extensión de cifrado que viene con wxSQLite3. Vea mi respuesta a una pregunta similar para más detalles.
Ulrich Telle
1
@RobotMess: Para ser honesto, ninguno de los que se enumeran aquí. Tenía estrictas limitaciones de tiempo en ese proyecto, así que tuve que hacer algo rápido. Fui con lo que mejor sabía: AES en los datos en bruto antes de colocarlos en la base de datos ... Aunque no es muy eficiente en términos de búsqueda, búsqueda y gestión de bases de datos.
ahmd0
@ ahmd0 Hm, ¿eso no hace que la DB sea algo inútil? Quiero decir, todo lo que realmente hace ahora es garantizar que los commits sean atómicos.
Navin
Si es posible. Si apunta a .Net Standard 4.6.1+ o Core, creo que una forma bastante sencilla de obtener el cifrado Sqlite es usar Microsoft.Data.Sqlite según mi respuesta aquí .
paulyb

Respuestas:

110

SQLite tiene ganchos integrados para el cifrado que no se usan en la distribución normal, pero aquí hay algunas implementaciones que conozco:

  • VER - La implementación oficial.
  • wxSQLite : un contenedor de C ++ estilo wxWidgets que también implementa el cifrado de SQLite.
  • SQLCipher : utiliza el libcrypto de openSSL para implementar.
  • SQLiteCrypt : implementación personalizada, API modificada.
  • botansqlite3 : botansqlite3 es un códec de cifrado para SQLite3 que puede usar cualquier algoritmo en Botan para el cifrado.
  • sqleet : otra implementación de cifrado que utiliza primitivas ChaCha20 / Poly1305. Tenga en cuenta que wxSQLite mencionado anteriormente puede usar esto como un proveedor de cifrado.

SEE y SQLiteCrypt requieren la compra de una licencia.

Divulgación: creé botansqlite3.

OliJG
fuente
1
¿Tiene alguna documentación de How-To-Use Botan para el cifrado de bases de datos SQLite? El sitio web de Botan no menciona esta característica.
Marc Schlösser
55
botansqlite3 ahora se distribuye independientemente de Botan.
OliJG
1
También hay litereplica . Utiliza el cifrado ChaCha, más rápido que AES en dispositivos portátiles basados ​​en ARMv7
Bernardo Ramos
SQLite3 .Net como soporte integrado para el cifrado ahora, lo que invalida en gran medida esta respuesta.
Krythic
21

Puede proteger con contraseña SQLite3 DB. Por primera vez antes de realizar cualquier operación, configure la contraseña de la siguiente manera.

SQLiteConnection conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
conn.SetPassword("password");
conn.open();

entonces la próxima vez puedes acceder como

conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;Password=password;");
conn.Open();

Esto no permitirá que ningún editor de GUI vea sus datos. Más adelante, si desea cambiar la contraseña, use conn.ChangePassword("new_password"); Para restablecer o eliminar la contraseña, useconn.ChangePassword(String.Empty);

Mangesh
fuente
16
No funcionará con el código abierto Sqlite. No tengo idea de qué implementación de idioma, idioma o API se supone que es.
mikerobi
1
¿Cómo sé qué forma de cifrado ChangePasswordutilicé? AES 128? RSA ..?
qakmak
1
RSA 1024 o 2048? ¿Hay algún documento que pueda ver más detalles?
qakmak
Obtenga los documentos desde aquí system.data.sqlite.org/index.html/doc/trunk/www/index.wiki
Mangesh
En mis propias pruebas, descubrí que el SetPasswordmétodo (en este momento) parece básicamente inútil. La única forma en que pude hacer que la System.Data.SQLitebiblioteca aplicara correctamente la contraseña fue usando el ChangePasswordmétodo. Utilizando SetPassword( antes de llamar al Openmétodo, como aparentemente es requerido por la biblioteca), todavía podía abrir y editar la base de datos en SQLiteStudio sin ninguna contraseña. No fue hasta que usé el ChangePasswordmétodo ( después de llamar al Openmétodo) que la aplicación de contraseña realmente "se atascó".
G_Hosa_Phat
15

La biblioteca .net System.Data.SQLite también proporciona cifrado.

Rory
fuente
8
ASP.NET! = SQL Server! = Instancia instalada de SQL Server
Zev Spitz
1
Pero System.Data.SQLite no es de Microsoft. Esta pregunta no se trata de .Net, pero si fuera así, otras compatibilidades e incompatibilidades serían importantes.
user34660
7

Puede obtener sqlite3.dllarchivos con soporte de cifrado en http://system.data.sqlite.org/ .

1 - Vaya a http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki y descargue uno de los paquetes. La versión .NET es irrelevante aquí.

2 - Extraer SQLite.Interop.dlldel paquete y renombrarlo a sqlite3.dll. Esta DLL admite el cifrado mediante contraseñas de texto sin formato o claves de cifrado.

El archivo mencionado es nativo y NO requiere .NET framework. Es posible que necesite Visual C ++ Runtime dependiendo del paquete que haya descargado.

ACTUALIZAR

Este es el paquete que he descargado para el desarrollo de 32 bits: http://system.data.sqlite.org/blobs/1.0.94.0/sqlite-netFx40-static-binary-Win32-2010-1.0.94.0.zip

Mohammad Banisaeid
fuente
En mi ejemplo particular, necesitaba un .libque pudiera incrustar en mi ejecutable. No podría tener ningún dlls.
ahmd0
2
Por favor, también comprobar éste github.com/rindeal/wxSQLite3-VS que le dará una liby dllarchivo.
Mohammad Banisaeid
4

Tenga en cuenta que lo siguiente no pretende ser un sustituto de una solución de seguridad adecuada.

Después de jugar con esto durante cuatro días, armé una solución usando solo el paquete de código abierto System.Data.SQLite de NuGet. No sé cuánta protección proporciona esto. Solo lo estoy usando para mi propio curso de estudio. Esto creará la base de datos, la encriptará, creará una tabla y agregará datos.

using System.Data.SQLite;

namespace EncryptDB
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = @"C:\Programming\sqlite3\db.db";
            string passwordString = "password";
            byte[] passwordBytes = GetBytes(passwordString);
            SQLiteConnection.CreateFile(connectionString);
            SQLiteConnection conn = new SQLiteConnection("Data Source=" + connectionString + ";Version=3;");
            conn.SetPassword(passwordBytes);
            conn.Open();
            SQLiteCommand sqlCmd = new SQLiteCommand("CREATE TABLE data(filename TEXT, filepath TEXT, filelength INTEGER, directory TEXT)", conn);
            sqlCmd.ExecuteNonQuery();
            sqlCmd = new SQLiteCommand("INSERT INTO data VALUES('name', 'path', 200, 'dir')", conn);
            sqlCmd.ExecuteNonQuery();
            conn.Close();
        }
        static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            bytes = System.Text.Encoding.Default.GetBytes(str);
            return bytes;
        }
    }
}

Opcionalmente, puede eliminarlo conn.SetPassword(passwordBytes);y reemplazarlo con el conn.ChangePassword("password");que debe colocarse después en conn.Open();lugar de antes. Entonces no necesitará el método GetBytes.

Para descifrar, solo es cuestión de poner la contraseña en su cadena de conexión antes de que se abra la llamada.

        string filename = @"C:\Programming\sqlite3\db.db";
        string passwordString = "password";
        SQLiteConnection conn = new SQLiteConnection("Data Source=" + filename + ";Version=3;Password=" + passwordString + ";");
        conn.Open();
Mike Warner
fuente
2
"I think I saw 128 bit somewhere"- esta es una muy mala declaración si planea lidiar con el cifrado. La regla general es que nunca lo haces tú mismo si no lo entiendes. De lo contrario, sería mejor no usarlo en absoluto.
ahmd0
Entiendo tu argumento. Principalmente intentaba corregir el consejo que he estado viendo que no funciona con la versión actual de System.Data.Sqlite. No quise decir que esto fuera una buena seguridad. He actualizado mi publicación. ¡Gracias por el aporte!
Mike Warner
2

Siempre puede cifrar datos en el lado del cliente. Tenga en cuenta que no todos los datos deben cifrarse porque tienen un problema de rendimiento.

Marcin
fuente
1

Pues SEEes caro. Sin embargo, SQLitetiene una interfaz incorporada para el cifrado (Pager). Esto significa que, además del código existente, uno puede desarrollar fácilmente algún mecanismo de cifrado, no es necesario AES. Cualquier cosa en realidad. Por favor, vea mi publicación aquí: https://stackoverflow.com/a/49161716/9418360

Debe definir SQLITE_HAS_CODEC = 1 para habilitar el cifrado de buscapersonas. Código de muestra a continuación ( SQLitefuente original ):

#ifdef SQLITE_HAS_CODEC
/*
** This function is called by the wal module when writing page content
** into the log file.
**
** This function returns a pointer to a buffer containing the encrypted
** page content. If a malloc fails, this function may return NULL.
*/
SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
  void *aData = 0;
  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
  return aData;
}
#endif

Existe una versión comercial C languagepara el SQLitecifrado con AES256; también puede funcionar PHP, pero debe compilarse PHPy SQLiteampliarse. Des / encripta el SQLitearchivo de la base de datos sobre la marcha, el contenido del archivo siempre está encriptado. Muy útil.

http://www.iqx7.com/products/sqlite-encryption

q74
fuente
0

Puede usar las rutinas de creación de funciones de SQLite ( manual de PHP ):

$db_obj->sqliteCreateFunction('Encrypt', 'MyEncryptFunction', 2);
$db_obj->sqliteCreateFunction('Decrypt', 'MyDecryptFunction', 2);

Al insertar datos, puede usar la función de cifrado directamente e INSERTAR los datos cifrados o puede usar la función personalizada y pasar datos no cifrados:

$insert_obj = $db_obj->prepare('INSERT INTO table (Clear, Encrypted) ' .
 'VALUES (:clear, Encrypt(:data, "' . $passwordhash_str . '"))');

Al recuperar datos, también puede usar la funcionalidad de búsqueda SQL:

$select_obj = $db_obj->prepare('SELECT Clear, ' .
 'Decrypt(Encrypted, "' . $passwordhash_str . '") AS PlainText FROM table ' .
 'WHERE PlainText LIKE :searchterm');
Alien426
fuente