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

您所在的位置:网站首页 字节转换成mb转换器 在EF Core中为数据表按列加密存储

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

2023-04-10 21:43| 来源: 网络整理| 查看: 265

假设有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列,需要加密存储,该如何实现?

在这里插入图片描述

创建一个值转换器,继承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列已被加密了

在这里插入图片描述

本文来自博客园,作者:林晓lx,转载请注明原文链接:https://www.cnblogs.com/jevonsflash/p/17288803.html



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3