EntityFrameworkCore数据加密存储解决方案


我们平时项目中,有很多数据其实是需要加密存储的,但是我们基本上都只是将密码进行加密存储,如果我们的用户银行卡信息,身份证信息,这些要进行明文显示,但是如果数据泄露,也能保护用户数据的就更好了,今天给大家介绍的就是这样的一个解决方案。

1 、创建一个项目,添加引用

EntityFrameworkCore.DataEncryption 
Pomelo.EntityFrameworkCore.MySql 

EntityFrameworkCore.DataEncryption 就是我们今天要介绍的主角。 

2 、建表,我模拟一个用户表,表结构如下

CREATETABLE`userinfo`  ( 
 `UserId`varchar ( 50 ) NOTNULL , 
 `UserName`varchar ( 255 ) DEFAULTNULL , 
 `Age`int ( 11 ) DEFAULTNULL , 
 `BankNum`varchar ( 500 ) DEFAULTNULL , 
PRIMARYKEY ( `UserId` )
 )  ENGINE=InnoDBDEFAULTCHARSET=utf8; 

其中 BankNum 是银行账号,注意,因为要存储加密字符串,所以字段长度要留长一点 

3 、项目中创建一个 userinfo 的实体类

publicclassUserInfo 
{ 
 /// 
 /// 用户 ID 
 /// 
 [  Key  ] 
publicstringUserId { get;set; }

 /// 
 /// 用户名
 /// 
publicstringUserName { get;set; }

 /// 
 /// 用户年龄
 /// 
publicintAge { get;set; }

 /// 
 /// 银行卡号
 /// 
 [  Encrypted  ] 
publicstringBankNum { get;set; }

 }

在 BankNum 上我们加了 EncryptedAttribute , 表示这个字段需要加密; 

4 、创建 TestContext ,添加构造函数,并在 OnModelCreating 方法中配置我们加密的 provider 

usingSystem; 
usingSystem.Text; 
usingDataEncryptionDemo.Entitys; 
usingMicrosoft.EntityFrameworkCore; 
usingMicrosoft.EntityFrameworkCore.DataEncryption; 
usingMicrosoft.EntityFrameworkCore.DataEncryption.Providers; 

namespaceDataEncryptionDemo 
{ 
publicclassTestContext : DbContext 
{ 
privatereadonlybyte []_ encryptionKey=Encoding.Default.GetBytes ( "4A7D1ED414474E4033AC29CCB8653D9B" ) ; 
privatereadonlybyte []_ encryptionIV=Encoding.Default.GetBytes ( "0019DA6F1F30D07C51EBC5FCA1AC7DA6".Substring ( 0 , 16 )) ; 
privatereadonlyIEncryptionProvider _ provider; 
publicTestContext  (  ) 
{ 
this ._ provider=newAesProvider ( this ._ encryptionKey , this ._ encryptionIV ) ; 
 }

 /// 
 /// 配置
 /// 
protectedoverridevoidOnConfiguring ( DbContextOptionsBuilderoptionsBuilder )
{ 
varconnectionString="server=127.0.0.1;port=3306;userid=root;password=123456;database=test;"; 
varserverVersion=newMySqlServerVersion ( newVersion ( 5 , 7 , 30 )) ; 
optionsBuilder.UseMySql ( connectionString , serverVersion ) ; 
 }

 /// 
 /// 用户表对象
 /// 
publicDbSetUserInfo { get;set; }

 /// 
 /// 实体对象的配置
 /// 
protectedoverridevoidOnModelCreating ( ModelBuildermodelBuilder )
{ 
modelBuilder.UseEncryption ( this ._ provider ) ; 
 }
 }
 }

到这里就开发完成了,是不是还挺简单

5 、试一下

TestContextcontext=newTestContext  (  )  ; 
UserInfozhangsan=newUserInfo { UserId=Guid.NewGuid  (  ).ToString  (  ) , UserName=" 张三 " , Age=15 , BankNum="123456789101112131415" } ; 
UserInfolisi=newUserInfo { UserId=Guid.NewGuid  (  ).ToString  (  ) , UserName=" 李四 " , Age=20 , BankNum="987654312222222233344" } ; 
context.UserInfo.AddRange ( zhangsan , lisi ) ; 
context.SaveChanges  (  )  ; 

varusers=context.UserInfo.ToList  (  )  ; 
foreach ( varuserinusers )
{ 
  Console.WriteLine ( $" { user.UserId }{ user.UserName }{ user.Age }{ user.BankNum } " ) ; 
 }
Console.WriteLine ( "HelloWorld!" ) ;

看界面输出

 没啥变化,银行卡还是明文的,但是你看数据库存储的

总结:优点就在于,最小化影响我们使用,还能解决加密的问题,所以就目前看来,使用上没有任何影响。

加密方式也分多种,可以进行配置