SQLite com proteção de criptografia / senha

136

Estou apenas aprendendo a usar o SQLite e fiquei curioso para saber se isso é possível:

  1. Criptografia do arquivo de banco de dados?

  2. Proteger com senha a abertura do banco de dados?

PS. Eu sei que existe esta "Extensão de Criptografia SQLite (SEE).", Mas de acordo com a documentação "O SEE é um software licenciado ..." e "O custo de uma licença de código-fonte perpétua para o SEE é de US $ 2000".

ahmd0
fonte
Certamente é possível e existem várias soluções de código aberto além do SEE. Entre eles, a extensão de criptografia fornecida com o wxSQLite3. Veja minha resposta a uma pergunta semelhante para obter detalhes.
precisa
1
@ RobotMess: Para ser sincero com você - nenhum dos listados aqui. Eu tinha restrições de tempo estritas nesse projeto, então tive que fazer algo rápido. Fui com o que sabia melhor - o AES nos dados brutos antes de colocá-los no banco de dados ... Embora não seja muito eficiente em termos de pesquisa, pesquisa e gerenciamento de banco de dados.
precisa saber é o seguinte
@ ahmd0 Hm, isso não torna o DB meio inútil? Quero dizer, tudo o que realmente faz agora é garantir que as confirmações sejam atômicas.
Navin
Sim é possivel. Se estiver direcionando o .Net Standard 4.6.1+ ou Core, acho bastante simples obter criptografia Sqlite é usar o Microsoft.Data.Sqlite conforme minha resposta aqui .
paulyb 31/03

Respostas:

110

O SQLite possui ganchos internos para criptografia que não são usados ​​na distribuição normal, mas aqui estão algumas implementações que eu conheço:

  • VER - A implementação oficial.
  • wxSQLite - Um invólucro C ++ no estilo wxWidgets que também implementa a criptografia do SQLite.
  • SQLCipher - Usa o libcrypto do openSSL para implementar.
  • SQLiteCrypt - Implementação personalizada, API modificada.
  • botansqlite3 - botansqlite3 é um codec de criptografia para SQLite3 que pode usar qualquer algoritmo no Botan para criptografia.
  • sqleet - outra implementação de criptografia, usando as primitivas ChaCha20 / Poly1305. Observe que o wxSQLite mencionado acima pode usar isso como um provedor de criptografia.

O SEE e o SQLiteCrypt requerem a compra de uma licença.

Divulgação: criei o botansqlite3.

OliJG
fonte
1
Você tem alguma documentação do How to Use Botan for SQLite criptografia de banco de dados? O site Botan não menciona esse recurso.
Marc Schlösser
5
O botansqlite3 agora é distribuído independentemente do Botan.
precisa saber é
1
Há também litereplica . Ele usa a cifra ChaCha, mais rápido do que AES em dispositivos portáteis com base em ARMv7
Bernardo Ramos
SQLite3 .Net, como suporte interno à criptografia agora, o que invalida amplamente essa resposta.
Krythic
21

Você pode proteger com senha o SQLite3 DB. Pela primeira vez antes de executar qualquer operação, defina a senha da seguinte maneira.

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

da próxima vez você pode acessá-lo como

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

Isso não permitirá que nenhum editor de GUI visualize seus dados. Posteriormente, se desejar alterar a senha, use conn.ChangePassword("new_password"); Para redefinir ou remover a senha, useconn.ChangePassword(String.Empty);

Mangesh
fonte
16
Não funcionará com o Sqlite de código aberto. Não há idéia de qual implementação de idioma, idioma ou API deve ser.
mikerobi
1
Como sei qual a maneira de criptografia ChangePasswordusada? AES 128? RSA ..?
precisa saber é
1
RSA 1024 ou 2048? Existe algum documento que veja mais detalhes?
qakmak
Em meus próprios testes, descobri que o SetPasswordmétodo (no momento) parece basicamente inútil. A única maneira de conseguir que a System.Data.SQLitebiblioteca aplique corretamente a senha foi usando o ChangePasswordmétodo Usando SetPassword( antes de chamar o Openmétodo, como aparentemente é exigido pela biblioteca), eu ainda conseguia abrir e editar o banco de dados no SQLiteStudio sem nenhuma senha. Não foi até eu usar o ChangePasswordmétodo ( depois de chamá-lo Open) que o aplicativo de senha realmente "travou".
G_Hosa_Phat 18/03
15

A biblioteca .net System.Data.SQLite também fornece criptografia.

Rory
fonte
8
ASP.NET! = SQL Server! = Instância instalada do SQL Server
Zev Spitz 09/09
1
Mas System.Data.SQLite não é da Microsoft. Esta questão não é sobre .Net, mas se fosse, outras compatibilidades e incompatibilidades seriam importantes.
user34660
7

Você pode obter sqlite3.dllarquivos com suporte à criptografia em http://system.data.sqlite.org/ .

1 - Acesse http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki e baixe um dos pacotes. A versão do .NET é irrelevante aqui.

2 - Extraia SQLite.Interop.dlldo pacote e renomeie-o para sqlite3.dll. Essa DLL oferece suporte à criptografia por meio de senhas de texto sem formatação ou chaves de criptografia.

O arquivo mencionado é nativo e NÃO requer a estrutura .NET. Pode ser necessário o Visual C ++ Runtime, dependendo do pacote que você baixou.

ATUALIZAR

Este é o pacote que baixei para o desenvolvimento 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
fonte
No meu exemplo em particular, eu precisava de um .libque pudesse incorporar ao meu executável. Eu não poderia ter nenhuma DLL.
precisa saber é o seguinte
2
Verifique também este github.com/rindeal/wxSQLite3-VS, que fornecerá um arquivo libe dll.
Mohammad Banisaeid
4

Lembre-se de que o seguinte não pretende substituir uma solução de segurança adequada.

Depois de brincar com isso por quatro dias, montei uma solução usando apenas o pacote System.Data.SQLite de código aberto do NuGet. Não sei quanta proteção isso fornece. Só o estou usando no meu curso de estudos. Isso criará o banco de dados, criptografará, criará uma tabela e incluirá dados.

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, você pode removê- conn.SetPassword(passwordBytes);lo e substituí-lo pelo conn.ChangePassword("password");qual precisa ser colocado depois e conn.Open();não antes. Então você não precisará do método GetBytes.

Para descriptografar, é apenas uma questão de colocar a senha na cadeia de conexão antes da abertura da chamada.

        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
fonte
2
"I think I saw 128 bit somewhere"- esta é uma afirmação muito ruim se você planeja lidar com criptografia. A regra geral é que você nunca faz isso sozinho, se não o entende. Caso contrário, seria melhor não usá-lo.
ahmd0
Eu entendo o seu ponto. Eu estava principalmente tentando corrigir os conselhos que tenho visto que não funcionam com a versão atual do System.Data.Sqlite. Eu não quis dizer que isso era uma boa segurança. Eu atualizei minha postagem. Obrigado pela contribuição!
Mike Warner
2

Você sempre pode criptografar dados no lado do cliente. Observe que nem todos os dados precisam ser criptografados porque há um problema de desempenho.

Marcin
fonte
1

Bem, SEEé caro. No entanto, SQLitepossui interface integrada para criptografia (Pager). Isso significa que, além do código existente, é possível desenvolver facilmente algum mecanismo de criptografia, não precisa ser assim AES. Qualquer coisa, mesmo. Por favor, veja o meu post aqui: https://stackoverflow.com/a/49161716/9418360

Você precisa definir SQLITE_HAS_CODEC = 1 para ativar a criptografia do Pager. Código de exemplo abaixo ( SQLitefonte 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 uma versão comercial C languagepara SQLitecriptografia usando o AES256 - ela também pode funcionar PHP, mas precisa ser compilada PHPe SQLiteampliada. De / criptografa o SQLitearquivo do banco de dados em tempo real, o conteúdo do arquivo é sempre criptografado. Muito útil.

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

q74
fonte
0

Você pode usar as rotinas de criação de funções do SQLite ( manual PHP ):

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

Ao inserir dados, você pode usar a função de criptografia diretamente e INSERIR os dados criptografados ou pode usar a função personalizada e transmitir dados não criptografados:

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

Ao recuperar dados, você também pode usar a funcionalidade de pesquisa SQL:

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