Öffnen verschlüsselter SQLite-DBs mit EF-Core

Veröffentlicht von

Hier ein Beispiel, wie man mit Entity Framework Core (EFCore) eine verschlüsselte SQLite-DB öffenen kann.

Ich habe das ganze mit net6.0 getestet.

Schritte zur Verwendung einer verschlüsselten SQLite-DB in einer .Net-Anwendung mit EFCore
  • Das NuGET-Paket Microsoft.EntityFrameworkCore hinzufügen
  • Das NuGET-Paket Microsoft.EntityFrameworkCore.Design hinzufügen
  • Das NuGET-Paket Microsoft.EntityFrameworkCore.Sqlite.Core hinzufügen
  • Das NuGET-Paket SQLitePCLRaw.bundle_e_sqlcipher hinzufügen
  • ACHTUNG: Das NuGET-Paket Microsoft.EntityFrameworkCore.Sqlite darf NICHT hinzufügt werden, sonst funktioniert es nicht
  • Wir erstellen einVerbindungsobjekt (SqliteConnection) und definieren das Datenbankzugriffspasswort in dem connection string (dazu verwenden wir SqliteConnectionStringBuilder)
  • Danach übergeben wir das Verbindungsobjekt an die UseSqlite-Methode
Einstellungen zur Verschlüsselung

Als erstes erstellen wir eine SQLite-DB, die wir nach dem erstellen verschlüsseln, ich nutze dafür „DB Browser for SQLite„.

Um die SQLite-DB zu verschlüsseln geht man im Menü auf Werkzeuge -> Verschlüsselung setzen…

Die Einstellungen sind schnell gemacht (siehe Bild), man muss eigentlich nur noch das Passwort eintragen und auf OK klicken.

Der Code

Model.cs

using System.Collections.Generic;

namespace ConsoleApp.SQLite
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }

        public List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
}Code-Sprache: JavaScript (javascript)

ConsoleApp.SQLite.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="6.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.7" />
  </ItemGroup>
</Project>Code-Sprache: HTML, XML (xml)

BloggingContext.cs

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

namespace ConsoleApp.SQLite
{
    public class BloggingContext : DbContext
    {
        public const string DEFAULTDBFILE = "blogging.db";

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        private readonly string dbFile = DEFAULTDBFILE;
        private SqliteConnection connection;

        public BloggingContext() { }

        public BloggingContext(string databaseFile)
        {
            if(!string.IsNullOrEmpty(databaseFile)) dbFile = databaseFile;
        }

        public BloggingContext(SqliteConnection sqliteConnection)
        {
            if (!string.IsNullOrEmpty(sqliteConnection?.DataSource)) dbFile = sqliteConnection.DataSource;
            connection = sqliteConnection;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            connection ??= InitializeSQLiteConnection(dbFile);
            optionsBuilder.UseSqlite(connection);
        }

        private static SqliteConnection InitializeSQLiteConnection(string databaseFile)
        {
            var connectionString = new SqliteConnectionStringBuilder
            {
                DataSource = databaseFile,
                Password = "Test123"// PRAGMA key is being sent from EF Core directly after opening the connection
            };
            return new SqliteConnection(connectionString.ToString());
        }
    }
}Code-Sprache: HTML, XML (xml)

Program.cs

Console.WriteLine("Hello, World!");

var db = new BloggingContext();

foreach (var item in db.Blogs)
{
    Console.WriteLine("item.BlogId: " + item.BlogId);
}Code-Sprache: PHP (php)
Quelle