Шифрование SQLite не работает (Microsoft.Data.Sqlite.Core и SQLitePCLRaw.bundle_e_sqlcipher)C#

Место общения программистов C#
Ответить
Anonymous
 Шифрование SQLite не работает (Microsoft.Data.Sqlite.Core и SQLitePCLRaw.bundle_e_sqlcipher)

Сообщение Anonymous »

Я следую этому руководству:
https://learn.microsoft.com/en-us/dotne ... bs=net-cli
Я использую эту версию .NET:
9.0.306 [C:\Program Files\dotnet\sdk]
У меня есть база данных Sqlite3.
Некоторые подробности:
$ file Core.db
Core.db: SQLite 3.x database, last written using SQLite version 3046001, file counter 4732, database pages 524, cookie 0x106, schema 4, UTF-8, version-valid-for 4732

Я запустил:
dotnet remove package Microsoft.Data.Sqlite
dotnet add package Microsoft.Data.Sqlite.Core
dotnet add package SQLitePCLRaw.bundle_e_sqlcipher

Я могу открыть базу данных с помощью Microsoft.Data.Sqlite без каких-либо проблем и выполнить любой оператор SQL, который захочу, с нормальным поведением.
Когда я запускаю это (как сказано в разделе «Укажите ключ»):
var connectionString = new SqliteConnectionStringBuilder(baseConnectionString)
{
Mode = SqliteOpenMode.ReadWriteCreate,
Password = password
}.ToString();

Я получаю:
Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 26: 'file is not a database'.

Я предполагал, что сначала мне нужно это сделать (позже в руководстве):
var commandPassword = connection.CreateCommand();
commandPassword.CommandText = "PRAGMA rekey = MyGreatPassword";
commandPassword.Parameters.Clear();
commandPassword.ExecuteNonQuery();

Это компилируется, запускается, без ошибок. Но когда я повторно открываю свою базу данных со строкой подключения, в которой не указан какой-либо пароль, все работает. И это не должно быть так. Он должен быть зашифрован.
Что мне не хватает?
1/ Вот полный MRE, вдохновленный https://github.com/dotnet/docs/blob/mai ... Program.cs:
using System;
using System.IO;
using Microsoft.Data.Sqlite;

using static SQLitePCL.raw;

namespace EncryptionSample
{
class Program
{
static void Main()
{
const string baseConnectionString = "Data Source=EncryptionSample.db";
var password = "...";

// 1 - Create a database WITHOUT a password
var connectionString = new SqliteConnectionStringBuilder(baseConnectionString)
{
Mode = SqliteOpenMode.ReadWriteCreate
}.ToString();

using (var connection = new SqliteConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = @"
CREATE TABLE data (
value TEXT
);

INSERT INTO data
VALUES ('Hello, encryption!');
";
command.ExecuteNonQuery();
connection.Close();
}

// 2 - Try to set a password to that non-encrypted database
connectionString = new SqliteConnectionStringBuilder(baseConnectionString)
{
Mode = SqliteOpenMode.ReadWrite,
Password = password
}.ToString();

using (var connection = new SqliteConnection(connectionString))
{
try
{
// This will throw
connection.Open();
}
catch (SqliteException ex) when (ex.SqliteErrorCode == SQLITE_NOTADB)
{
Console.WriteLine("Access denied.");
}
}
}
}
}

2/ Вот второй полный MRE, показывающий, что PRAGMA на самом деле не добавляет пароль:
using System;
using System.IO;
using Microsoft.Data.Sqlite;

using static SQLitePCL.raw;

namespace EncryptionSample
{
class Program
{
static void Main()
{
const string baseConnectionString = "Data Source=EncryptionSample.db";
var password = "...";

// 1 - Create a database WITHOUT a password
var connectionString = new SqliteConnectionStringBuilder(baseConnectionString)
{
Mode = SqliteOpenMode.ReadWriteCreate
}.ToString();

using (var connection = new SqliteConnection(connectionString))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = @"
CREATE TABLE data (
value TEXT
);

INSERT INTO data
VALUES ('Hello, encryption!');
";
command.ExecuteNonQuery();
connection.Close();
}

// 2 - Set a password to that non-encrypted database
using (var connection = new SqliteConnection(connectionString))
{
connection.Open();
var commandPassword = connection.CreateCommand();
commandPassword.CommandText = "SELECT quote($newPassword);";
commandPassword.Parameters.AddWithValue("$newPassword", ("myNewPassword"));
var quotedNewPassword = (string)commandPassword.ExecuteScalar();

commandPassword.CommandText = "PRAGMA rekey = " + quotedNewPassword;
commandPassword.Parameters.Clear();
commandPassword.ExecuteNonQuery();
}

// 3 - Reopen without specifying the password. this shouldn't work! But it does.
using (var connection = new SqliteConnection(connectionString))
{
connection.Open();
var queryCommand = connection.CreateCommand();
queryCommand.CommandText =
@"
SELECT value
FROM data
LIMIT 1
";
var value = (string)queryCommand.ExecuteScalar();
Console.WriteLine(value);
connection.Close();
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... pclraw-bun
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»