You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除数据库中所有Data Protection密钥后解密仍生效的原因?

为何删除数据库中所有.NET Data Protection密钥后仍能解密?

我在项目中使用.NET Data Protection组件,相关代码如下:

初始化密钥代码

ServiceProvider services;
private void InitializeKeys()
{
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddDbContext<MyContext>();
    serviceCollection.AddDataProtection().SetDefaultKeyLifetime(TimeSpan.FromDays(14)).PersistKeysToDbContext<MyContext>();
    services = serviceCollection.BuildServiceProvider();
    services.GetDataProtector("MyClass.v1").Protect("payload");
}

MyContext代码

public class MyContext : DbContext, IDataProtectionKeyContext
{
    public MyContext()
    {

    }

    public MyContext(DbContextOptions<MyContext> options) : base(options)
    {

    }

    public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } = null!;


    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=.;Database=ThisIsMyDB;Trusted_Connection=True;TrustServerCertificate=True");
    }
}

运行项目后,数据库中成功生成一个密钥,且加密操作完成。最初的加密代码如下:

var Provider = DataProtectionProvider.Create("MyClass.v1");
IDataProtector _protector = Provider.CreateProtector("MyClass.v1");
txtEncryptResult.Text = _protector.Protect(txtEncryptValue.Text);

随后我停止运行的应用,并删除了数据库中的所有密钥,但使用以下解密代码仍能成功解密之前得到的加密值:

var Provider = DataProtectionProvider.Create("MyClass.v1");
IDataProtector _protector = Provider.CreateProtector("MyClass.v1");
txtDecryptResult.Text = _protector.Unprotect(txtDecryptValue.Text);

请问为何删除所有密钥后解密仍能正常工作?


编辑1

根据@Dai的回答,我更新了加密代码,目前运行正常:

var Provider = services.GetDataProtector("MyClass.v1");
IDataProtector _protector = Provider.CreateProtector("MyClass.v1");
txtEncryptResult.Text = _protector.Protect(txtEncryptValue.Text);

问题原因分析

核心问题是加密操作并未使用你配置了数据库密钥持久化的Data Protection实例:

  • 你的InitializeKeys方法确实配置了将密钥持久化到数据库的Data Protection服务,但最初的加密代码通过DataProtectionProvider.Create("MyClass.v1")创建了一个全新的独立实例。
  • 这个默认创建的实例不会复用DI容器中配置的数据库持久化逻辑,而是使用.NET Data Protection的默认密钥存储位置(对于桌面应用,通常是用户目录下的AppData\Local\ASP.NET\DataProtection-Keys文件夹,而非你指定的数据库)。
  • 因此你之前的加密值实际是用本地文件系统中的密钥加密的,删除数据库密钥自然不会影响解密——因为解密时用的还是本地存储的那套密钥。

修正后的代码说明

你在编辑1中更新的代码改为从DI容器中获取IDataProtector实例,这才真正使用了你配置的、密钥持久化到数据库的Data Protection服务。此时如果删除数据库中的密钥,解密操作就会失败,符合预期。


内容的提问来源于stack exchange,提问作者DooDoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:02:42