Encrypt and decrypt EF Core string columns through value converters for .NET developers.
Use a .NET 10 console project. Install the packages, then replace Program.cs with the example.
dotnet new console -f net10.0 -n EfCoreDemo
cd EfCoreDemo
dotnet add package DKNet.EfCore.Encryption
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 10.0.12
using System.Security.Cryptography;
using DKNet.EfCore.Encryption;
using DKNet.EfCore.Encryption.Attributes;
using DKNet.EfCore.Encryption.Encryption;
using DKNet.EfCore.Encryption.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using var connection = new Microsoft.Data.Sqlite.SqliteConnection("Data Source=:memory:");
connection.Open();
var services = new ServiceCollection();
services.AddEfCoreEncryption<DemoKey>();
services.AddDbContext<DemoDb>(o => o.UseSqlite(connection));
using var provider = services.BuildServiceProvider();
using var scope = provider.CreateScope();
await using var db = scope.ServiceProvider.GetRequiredService<DemoDb>();
await db.Database.EnsureCreatedAsync();
db.Add(new Customer { Secret = "demo-value" });
await db.SaveChangesAsync();
db.ChangeTracker.Clear();
Console.WriteLine((await db.Customers.SingleAsync()).Secret); // demo-value
using var command = connection.CreateCommand();
command.CommandText = "SELECT Secret FROM Customers";
Console.WriteLine((string)command.ExecuteScalar()! != "demo-value"); // True
public sealed class DemoKey : IEncryptionKeyProvider
{
private readonly byte[] _key = RandomNumberGenerator.GetBytes(32);
public byte[] GetKey(Type entityType) => _key;
}
public sealed class DemoDb(DbContextOptions<DemoDb> options, IEncryptionKeyProvider keys) : DbContext(options)
{
public DbSet<Customer> Customers => Set<Customer>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.UseColumnEncryption(keys);
}
}
public sealed class Customer
{
public int Id { get; set; }
[Encrypted]
public string? Secret { get; set; }
}
Run with dotnet run.
Only EF Core is referenced by this package. AddEfCoreEncryption registers a singleton key provider; converters and their provider capture keys when the EF model is built. There is no SaveChanges hook or key-vault client.
The demo uses an ephemeral key only for its in-memory database. Persisted databases need a stable protected key across restarts. Null and empty strings pass through, while malformed or unauthenticated ciphertext throws.