在EF Core中为数据表按列加密存储

2023-04-05 08:28:53 来源:博客园


(资料图)

假设有User表

public class User : Entity{    public int Id { get; set; }    public string UserName { get; set; }    public string Name { get; set; }    public string IdentificationNumber { get; set; }}

其中有身份证号码IdentificationNumber列,需要加密存储,该如何实现?![在这里插入图片描述](https://img-blog.csdnimg.cn/a9edb9793cc841ff91391ec7d4d298d7.png

创建一个值转换器,继承ValueConverter类型。其中泛型TModel为实体中属性的类型。

转换器将实体中属性类型,通过AES加密算法,转换为Base64编码字符串类型,存储到数据库中。当从数据库中读取数据时,再通过AES解密算法,将Base64编码字符串类型转换为实体中属性类型。

若实体类型为byte[],则不需要转换为Base64编码字符串类型,直接对二进制数据进行加密和解密。此转换器可以用于加密存储图片、文件等二进制数据。

AES加密算法是一种对称加密算法,加密和解密使用相同的密钥。在加密和解密时,需要指定密钥、初始向量、盐值等参数。在转换器中,将这些参数设置为静态属性,方便在使用时,进行修改。

代码如下:

public class EncryptionConverter : ValueConverter{    public const int DefaultKeysize = 256;    public static string DefaultPassPhrase { get; set; }    public static byte[] DefaultInitVectorBytes { get; set; }    public static byte[] DefaultSalt { get; set; }    public EncryptionConverter()        : base(            x => Encrypt(x),            x => Decrypt(x))    {        DefaultPassPhrase = "gsKnGZ041HLL4IM8";        DefaultInitVectorBytes = Encoding.ASCII.GetBytes("jkE49230Tf093b42");        DefaultSalt = Encoding.ASCII.GetBytes("hgt!16kl");    }    private static string Encrypt(TModel input)    {        try        {            byte[] inputData = input switch            {                string => Encoding.UTF8.GetBytes(input.ToString()),                byte[] => input as byte[],                _ => null,            };            using (var password = new Rfc2898DeriveBytes(DefaultPassPhrase, DefaultSalt))            {                var keyBytes = password.GetBytes(DefaultKeysize / 8);                using (var symmetricKey = Aes.Create())                {                    symmetricKey.Mode = CipherMode.CBC;                    using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, DefaultInitVectorBytes))                    {                        using (var memoryStream = new MemoryStream())                        {                            using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))                            {                                cryptoStream.Write(inputData, 0, inputData.Length);                                cryptoStream.FlushFinalBlock();                                var cipherTextBytes = memoryStream.ToArray();                                var rawString = Convert.ToBase64String(cipherTextBytes);                                return rawString;                            }                        }                    }                }            }        }        catch (Exception ex)        {                          LogHelper.LogException(ex);            return input.ToString();                      }            }    private static TModel Decrypt(string input)    {        try        {            var cipherTextBytes = Convert.FromBase64String(input);            using (var password = new Rfc2898DeriveBytes(DefaultPassPhrase, DefaultSalt))            {                var keyBytes = password.GetBytes(DefaultKeysize / 8);                using (var symmetricKey = Aes.Create())                {                    symmetricKey.Mode = CipherMode.CBC;                    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, DefaultInitVectorBytes))                    {                        using (var memoryStream = new MemoryStream(cipherTextBytes))                        {                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))                            {                                var plainTextBytes = new byte[cipherTextBytes.Length];                                int totalDecryptedByteCount = 0;                                while (totalDecryptedByteCount < plainTextBytes.Length)                                {                                    var decryptedByteCount = cryptoStream.Read(                                        plainTextBytes,                                        totalDecryptedByteCount,                                        plainTextBytes.Length - totalDecryptedByteCount                                    );                                    if (decryptedByteCount == 0)                                    {                                        break;                                    }                                    totalDecryptedByteCount += decryptedByteCount;                                }                                byte[] outputData = null;                                if (typeof(TModel) == typeof(string))                                {                                    outputData = Encoding.UTF8.GetBytes(plainTextBytes.ToString());                                }                                else if (typeof(TModel) == typeof(byte[]))                                {                                    outputData = plainTextBytes as byte[];                                };                                var rawString = Encoding.UTF8.GetString(outputData, 0, totalDecryptedByteCount);                                return (TModel)Convert.ChangeType(rawString, typeof(TModel));                            }                        }                    }                }            }        }        catch (Exception ex)        {        // 记录异常            // LogHelper.LogException(ex);            return (TModel)Convert.ChangeType(input, typeof(TModel));        }    }}

DbContext中,重写OnModelCreating方法,为User表的IdentificationNumber列,添加值转换器。

protected override void OnModelCreating(ModelBuilder modelBuilder){    base.OnModelCreating(modelBuilder);    modelBuilder.Entity().Property(c => c.IdentificationNumber).HasConversion>();}

再次调用Add方法插入数据时,可以看到IdentificationNumber列已被加密了

标签:

在EF Core中为数据表按列加密存储

2023-04-05

世界时讯:“刀尖行走”的脑部高难手术打通生命中枢

2023-04-05

打造亚太旅游投资门户 第二届上海旅游投资促进大会在沪召开-世界热点评

2023-04-05

天天快播:体温摄氏度换算_体温摄氏度符号

2023-04-04

萝卜如何保存长久 萝卜怎么保存长久

2023-04-04

登山赛车小五_登山部落 快资讯

2023-04-04

世界最新:我们的节日·精神的家园丨嘉积镇:加强巡查教育 倡导文明祭扫

2023-04-04

世界关注:西媒:皇马今夏将听取对门迪报价,希望获得超4000万欧转会费

2023-04-04

2023重庆购车补贴申请流程

2023-04-04

4月4日A股分析:沪指涨0.49%,贵金属、半导体涨幅居前 每日资讯

2023-04-04

世界即时:针灸是如何发挥作用的?三地四校“云端”联动探索《神秘的东方力量》

2023-04-04

盘你什么意思是什么_盘你的意思

2023-04-04

热点评!右侧附件囊肿是什么原因_右侧附件囊肿严重吗怎么治疗

2023-04-04

为什么Spark是未来的大数据平台

2023-04-04

上古神器3攻略图片教程_上古神器3完全版攻略|世界微资讯

2023-04-04

天天精选!叶牛平任西安市委副书记 李明远不再担任

2023-04-04

世界即时看!无间:火鹤假叛实忠,花向雨不是青衣,真正的青衣已经浮出水面

2023-04-04

天天播报:沿着长江读懂中国 长江读书节第四届讲书人大赛启动

2023-04-04

当前热讯:中央政法委长安剑:“张继科”刷屏,要查清三件事

2023-04-04

【天天速看料】联创光电:4月3日融资买入4359.38万元,融资融券余额13.52亿元

2023-04-04

石四药集团(02005.HK):4月3日南向资金减持164万股|天天速看

2023-04-04

sacai x Nike 最新联名!鞋型选对了,只是……-全球视讯

2023-04-03

微动态丨今日如何注册qq账号不用其它手机验证_qq注册账号申请QQ号不用手机验证目前有效方法

2023-04-03

一场特殊的义诊!湖南省妇幼保健院为孤独症儿童进行免费筛查评估

2023-04-03

天天短讯!森马服饰最新公告:拟使用不超60亿元自有资金购买理财产品

2023-04-03

天味食品2022年度10转4派3.2元

2023-04-03

香港3月末持牌地产代理超4.1万人

2023-04-03

俄罗斯总检察院:俄在土耳其的帮助下制定经第三国引渡公民的过境运送方法,并得以应用-环球热讯

2023-04-03

当前播报:洛杉矶公开赛摘金,殷若宁成第二位LPGA夺冠的中国选手

2023-04-03

TA:切尔西女足与劳伦-詹姆斯已开始谈判,球队希望与她涨薪续约|环球新视野

2023-04-03

Copyright ©  2015-2022 世界频道网版权所有  备案号:琼ICP备2022009675号-1   联系邮箱:435 227 67@qq.com