gpt4 book ai didi

c# - 使用 Entity Framework 的加密列

转载 作者:可可西里 更新时间:2023-11-01 06:31:39 25 4
gpt4 key购买 nike

有人想出了一个通过 Entity Framework 4 从数据库中提取加密值的好方法吗?

我有一个 MySql 数据库,其中一些列使用 des_encrypt 加密,需要能够尽可能简单地获取这些值,当然还需要更新和插入它们。

我觉得很奇怪,EF 中似乎没有内置对此的支持。甚至我们自己构建的 ORM 系统也支持这一点。我们只需为每个加密的字段添加注释“加密”,ORM 工具将在查询中添加 des_decrypt(column) 和 des_encrypt(column)。

有人吗?

最佳答案

这是@TheCloudlessSky提出的答案的实现示例。我认为它会对任何想知道如何实现它的人有所帮助。

我使用的是现有数据库,因此自动为我生成了基本模型类。

自动生成的 User.cs:

namespace MyApp.Model 
{
public partial class User
{
public int UserId { get; set; }
public byte[] SSN { get; set; }
...
}
}

我创建了自己的 User.cs。 (请注意,它与自动生成的 User.cs 在同一个命名空间中,并且没有编译器错误,因为自动生成的 User.cs 被声明为 partial class!另外,我自己的 User.cs 不能由于文件名冲突,与自动生成的 User.cs 在同一文件夹中!)

namespace MyApp.Model 
{
public partial class User
{
public string DecryptedSSN { get; set; }
...
}
}

现在,每当我从我的 DbContext 中检索用户时,我都会看到在自动生成的类中定义的所有属性以及在我的增强类中定义的属性。

这是我的 UserRepository.cs 的实现:

namespace MyApp.Model
{
public interface IUserRepository
{
User Get(int userId);
...
}

public class UserRepository : IUserRepository
{
public User GetById(int userId)
{
using (var dataContext = MyDbContext())
{
var user = dataContext.Users.Find(u => u.UserId == userId);
var decryptedSSNResult = dataContext.Decrypt(u.SSN);
user.DecryptedSSN = decryptedSSNResult.FirstOrDefault();
return user;
}
}
}
}

现在您可能想知道我是如何/从哪里获得 MyDbContext.Decrypt() 的?

这不是为您自动生成的。但是,您可以将此存储过程导入到自动生成的 Model.Context.cs 文件中。 (此过程在 EntityFramework 官方文章中有详细记录:如何:在 http://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx 导入存储过程(实体数据模型工具))

如果您不知道最终结果应该是什么样子,下面是我的 Model.Context.cs 中自动生成的内容:

namespace MyApp.Model
{
// using statements found here

public partial class MyDbContext : DbContext
{
public MyDbContext()
: base("name = MyDbContext")
{ }

public virtual ObjectResult<string> Decrypt(byte[] encryptedData)
{
var encryptedDataParameter = encryptedData != null ?
new ObjectParameter("encryptedData", encryptedData) :
new ObjectParameter("encryptedData", typeof(byte[]));

return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<string>("Decrypt", encryptedDataParameter);
}

// similar function for Encrypt
}
}

这是我的解密存储过程的样子:

CREATE PROCEDURE decrypt
@encryptedData VARBINARY(8000)
AS
BEGIN
OPEN SYMMETRIC KEY xxx_Key DECRYPTION BY CERTIFICATE xxx_Cert;

SELECT CAST(DECRYPTIONBYKEY(@encryptedData) AS NVARCHAR(MAX)) AS data;

CLOSE ALL SYMMETRIC KEYS;
END;
GO

性能注意事项

既然我已经向您展示了@TheCloudlessSky 给出的答案的实现,我想快速强调一些与性能相关的要点。

1) 每次检索用户对象时,都会对数据库进行 2 次访问,而不是 1 次。检索对象的第一次访问;第二次解密SSN。如果您不小心,这可能会导致性能问题。

建议:不要自动解密加密字段!在上面显示的示例中,我在检索用户对象时解密了 SSN。我这样做只是为了演示目的!每次检索用户时,问问自己是否真的需要 SSN。如果可能,选择延迟解密而不是急切解密!

2) 虽然我没有演示这一点,但每次您创建/更新用户对象时,也会对数据库进行 2 次访问。第一次加密SSN;插入对象的第二次旅行。同样,如果您不小心,这可能会导致性能问题。

建议:注意这种性能影响,但不要将 SSN 的加密和保存委托(delegate)为不同的方法。将其全部保存在一个操作中,否则您可能会忘记将其完全保存。因此,创建/更新的建议与检索相反:选择急切加密而不是惰性加密!

关于c# - 使用 Entity Framework 的加密列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3299054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com