在实体框架上使用始终加密[代码优先]数据库

时间:2017-10-30 16:40:44

标签: entity-framework code-first identity dynamic-proxy always-encrypted

我有一个首先使用实体​​框架/代码的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')   collat​​ion_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不支持的事情吗?

3 个答案:

答案 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)

根据https://blogs.msdn.microsoft.com/sqlsecurity/2015/08/27/using-always-encrypted-with-entity-framework-6/

  

将常量参数传递为闭包-这将强制参数化,从而生成>正确的查询:

     

var ssn =“ 123-45-6789”;

     

context.Patients.Where(p => p.SSN == ssn);