我有一个首先使用实体框架/代码的MVC应用程序。我正在尝试设置始终加密以加密列(社会安全号码/ SSN)。我在Azure中运行所有内容,包括使用Azure保管库来存储密钥。
我有两个型号,SystemUser和Person。 SystemUser本质上是一个帐户/登录,可以管理1个或更多人。
定义看起来有点像:
public class Person
{
[StringLength(30)]
[Column(TypeName = "varchar")]
public string SSN { get; set; } // Social Security Number
...
[Required, MaxLength(128)]
public string SystemUserID { get; set; }
[ForeignKey("SystemUserID")]
public virtual SystemUser SystemUser { get; set; }
...
}
public class SystemUser
{
...
[ForeignKey("SystemUserID")]
public virtual HashSet<Person> People { get; set; }
...
}
我有一个非常基本的页面设置,只是查找用户并打印出他们的SSN。这有效。然后我调整了页面以更新SSN,这也有效。这对我来说意味着始终加密配置和Azure Vault已正确设置。我在连接字符串中有“Column Encryption Setting = Enabled”,我使用SSMS加密了SSN列(我使用的是确定性的)。
在我的SystemUser类中,我有以下方法作为Identity的实现:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<SystemUser> manager)
{
...
if (this.People.Any())
{
...
}
...
}
这用于用户登录。运行代码会产生:
System.Data.Entity.Core.EntityCommandExecutionException:错误 执行命令定义时发生。看到内心 细节例外。 ---&GT; System.Data.SqlClient.SqlException: 操作数类型冲突:varchar与varchar(30)加密不兼容 with(encryption_type ='DETERMINISTIC',encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name = 'CEK_Auto11',column_encryption_key_database_name ='xxx') collation_name ='Latin1_General_BIN2'
似乎在“if(this.People.Any())”上面的行上失败了。在该行之前设置一个断点就会发现以下内容。人们:
'((System.Data.Entity.DynamicProxies.SystemUser_9F939A0933F4A8A3724213CF7A287258E76B1C6775B69BD1823C0D0DB6A88360)这一点)。人们' 抛出了类型的例外 'System.Data.Entity.Core.EntityCommandExecutionException'System.Collections.Generic.HashSet {System.Data.Entity.Core.EntityCommandExecutionException}
这里有什么想法吗?我在做一些Always Encrypted不支持的事情吗?
答案 0 :(得分:1)
始终加密在实体框架中没有支持。 MS仍在工作。
答案 1 :(得分:1)
此博客Using Always Encrypted with Entity Framework 6解释了如何首先使用Always Encrypted with Entity Framework 6 for DataBase和Code First从现有数据库和Code first-Migrations中解决不同的场景和问题。
答案 2 :(得分:0)
将常量参数传递为闭包-这将强制参数化,从而生成>正确的查询:
var ssn =“ 123-45-6789”;
context.Patients.Where(p => p.SSN == ssn);