【问题标题】:SQLCipher integration into Xamarin.Forms; SQLite Library doesn't support encryption exceptionSQLCipher 集成到 Xamarin.Forms; SQLite 库不支持加密异常
【发布时间】:2020-05-22 14:49:35
【问题描述】:

我正在将 SQLCipher 实现到 Xamarin.Forms 应用程序中。我以为一切正常,直到我注意到 X.F. 正在创建的数据库。应用程序实际上是一个没有加密或密码的 SQLite3 数据库。研究了一段时间后,我一直无法找到解决方案。我遇到了一个异常,上面写着

System.InvalidOperationException: 'You specified a password in the connection string, but the native SQLite library you're using doesn't support encryption.'

我目前在此解决方案中有 4 个项目。 XamarinForms 中的标准 3(跨平台的默认 PCL、Project.Android 和 Project.iOS)。除了这 3 个之外,我还有一个名为 Project.Core 的自定义 PCL。此 PCL 负责所有 DataAccess,因为它实现了存储库模式、工作单元、DbContext 等。

在第 4 个项目中,在我的 DbContext.cs 类中,我有这个:

// Added for more context
using System;
using System.IO;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Xamarin.Forms;


private SqliteConnection connection;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
        string connStr = Path.Combine(
            path1: Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            path2: "App.db");

        string passStr = deviceIdentifier;

        string path = Path.GetDirectoryName(connStr);
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        // Check if db file exists
        if (!File.Exists(connStr))
        {
            FileStream stream = File.Create(connStr);
            stream.Close();
        }

        // DOCS => https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/encryption?tabs=netcore-cli
        // => https://www.bricelam.net/2016/06/13/sqlite-encryption.html
        var connectionString = new SqliteConnectionStringBuilder()
        {
            DataSource = connStr,
            Mode = SqliteOpenMode.ReadWriteCreate,
            Password = passStr
        }.ToString();

        // NOTE: THIS IS WHERE THE EXCEPTION IS THROWN!!!
        // THE CODE BELOW THIS IS AN ALTERNATE ROUTE THAT DOENS'T WORK EITHER
        **connection.Open();**

        // This code doesn't throw anything, but it doesn't key the DB either
        using (SqliteCommand command = connection.CreateCommand())
        {
            command.CommandText = "SELECT quote($password);";
            command.Parameters.AddWithValue("$password", passStr);
            string escapedPassword = (string)command.ExecuteScalar(); // Protects against SQL injection

            command.CommandText = "PRAGMA key = " + escapedPassword /*+ ";"*/;
            command.Parameters.Clear();
            command.ExecuteNonQuery();
        }

#if DEBUG
        optionsBuilder.EnableSensitiveDataLogging();
#endif

        optionsBuilder.UseSqlite(connection);
        SQLitePCL.Batteries_V2.Init();
}        

通过我的研究,此 PCL 中的 SQLite/SQLCipher 包之一可能存在问题(PCL 的目标是 .NET Standard 2.0 以供参考)。

我目前有:

  • Microsoft.Data.Sqlite.Core 3.1.1(依赖于 Microsoft.Data.Sqlite.dll 和 SQLitePCLRaw.core 2.0.2)
  • SQLitePCLRaw.bundle_sqlcipher 1.1.14(依赖于 SQLitePCLRaw.core 2.0.2、SQLitePCLRaw.batteries_sqlcipher.dll、SQLitePCLRaw.batteries_v2.dll)

还有几点需要注意:

  • 查看 SQLitePCL 命名空间时,它显示包为 sqlitepclraw.bundle_e_sqlite3,而不是引用 sqlcipher。 \.nuget\packages\sqlitepclraw.bundle_e_sqlite3\2.0.2\lib\netstandard2.0\SQLitePCLRaw.batteries_v2.dll
  • 我认为这种依赖可能存在问题,但我不确定,希望能提供任何帮助!

提前致谢。

PS - 可按要求提供更多信息

【问题讨论】:

    标签: c# sqlite xamarin.forms portable-class-library sqlcipher


    【解决方案1】:

    找到一个可行的解决方案。

    查看软件包后,我发现将现有的 SQLitePCLRaw 捆绑包替换为 SQLitePCLRaw.bundle_zetetic 发现 here,解决了连接和维护加密数据库的问题。

    工作代码sn-p是:

    // StringBuilder here, and the SqliteConnection below are 
    // from the Microsoft.Data.Sqlite namespace v3.1.1
    var connectionString = new SqliteConnectionStringBuilder()
    {
      DataSource = connStr,
      Mode = SqliteOpenMode.ReadWriteCreate,
      Password = passStr
    }.ToString();
    
    connection = new SqliteConnection(connectionString);
    connection.Open();
    

    【讨论】:

    • 您可以稍后标记它可以帮助更多有相同问题的人:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多