暴库也不怕!EF Core 加密存储数据

目录

针对某些数据字段要保存敏感数据的情况,比如银行卡号,我们需要使用一种机制保证存储到数据库的数据是加密的,避免数据泄露风险,但是又能够正常读取出来显示。

下面我们用 MySql 演示如何操作。

Demo

创建一个 ConsoleApp1,然后引用下列 NuGet 包:

  • EntityFrameworkCore.DataEncryption
  • Pomelo.EntityFrameworkCore.MySql

假设数据表 User 已创建好,包含 3 个字段:

  • Id 主键
  • Name 姓名
  • BankCard 银行账户

创建 User 类,在 BankCard 上我们加了 EncryptedAttribute,表示这个字段需要加密:

1
2
3
4
5
6
7
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Encrypted]
    public string BankCard { get; set; }
}

创建 DefaultDbContext,在构造函数创建 IEncryptionProvider 实例,并在 OnModelCreating 方法中 UseEncryption

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class DefaultDbContext: DbContext
{
    private readonly byte[] _encryptionKey = ...;
    private readonly byte[] _encryptionIV = ...;
    private readonly IEncryptionProvider _provider;
      
    public DefaultDbContext()
    {
        this._provider = new AesProvider(this._encryptionKey, this._encryptionIV);
    }

    public DbSet<User> User { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.UseEncryption(this._provider);
        base.OnModelCreating(modelBuilder);
    }
}

现在,让我们增加几个 User

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
DefaultDbContext context = new DefaultDbContext();

User zhangsan = new User { Id = 1, Name = "张三", BankCard = "12345" };
User lisi = new User { Id = 2, Name = "李四", BankCard = "67890" };
context.User.AddRange(zhangsan, lisi);
context.SaveChanges();

var users = context.User.ToList();
foreach (var user in users)
{
    Console.WriteLine($"{user.Id} {user.Name} {user.BankCard}");
}

可以看到输出正常

但是数据库里保存的是加密后的数据

结论

使用这种方式的好处在于,可以实现统一的数据库数据加解密规则,不需要单独在仓储中处理了,方便快速实现业务。

0%