1

我们在使用 EF6 和始终加密功能时遇到了一些问题。

我相信我们需要在 中设置一些东西DBContext,以指示如何加密或解密列,但我找不到这样做的方法。

我们已经有一个 ADO 访问层,它与加密字段完美配合。我们宁愿使用 EF 而不是 ADO。

症状是:

  1. 使用EF,我们可以查询数据。并且解密过程工作正常。
  2. 插入过程抛出以下错误:

操作数类型冲突:varchar 与使用 (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'Development_v2_qa') collat​​ion_name = _SQL_Latin_1_加密的 varchar(8000) 不兼容

  1. 使用 where 子句查询,使用加密字段,会引发相同的错误。

使用的技术:

  • 带有 Poco 实体的 EF6。
  • AzureKeyVault 用于存储加密/解密主密钥。
  • 使用 SSL 证书对 KeyVault 进行身份验证
  • 连接字符串包含“列加密设置=启用;”
  • AzureSqlServer
  • FWK4.6
  • ADO

我们有一些代码可以很好地与 ADO 配合使用。它适用于每个SqlConnection

// Instantiate our custom AKV column master key provider.
// It uses the GetToken function as the callback function to authenticate to AKV
SqlColumnEncryptionAzureKeyVaultProvider akvprov = new SqlColumnEncryptionAzureKeyVaultProvider();
akvprov.KeyVaultClient = SecureConfigurationManager.KeyVaultClient;
// Register the instance of custom provider to SqlConnection
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
// "SqlColumnEncryptionAzureKeyVaultProvider.ProviderName" is the name of the provider. It must match the string we used when we created the column master key
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvprov);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
4

2 回答 2

1

是的,我刚刚发现了同样的问题,需要添加

[Column(TypeName = "varchar(max)")]

在字段之前的 POCO 类型中以使其工作。如果错误更清楚一点就好了(如果NVARCHAR确实有效,那就更好了)

于 2017-10-18T00:26:50.780 回答
0

我正在解决同样的问题。问题在于从 C# 到数据库的数据类型映射。并非所有长度对于始终加密和使用 Entity Framework 的 varchars 都很重要,只有 varchar(max) 或 varchar(8000)。我的所有实体框架都使用 azure key vault 处理所有数据类型,和你一样。下面的这个链接显示了如何使用内联 SQL 进行插入。我只使用过实体框架,希望我永远不必使用内联 sql,即使我可能不得不这样做,如果我找不到一种方法来减少加密所需的数据库存储开销,或者看起来像Stretch Db,也是 SQL Server 2016 中的另一个功能。感谢 Jakub Szymaszek 和 Microsoft。

我已经承认并制作了我所有的数据类型 varchar(max) 并且它工作得很好。所以字符串 = varchar(max)。奇怪的是,加密中没有8000个字符,但分配了大概8000个。

“something1”在加密并插入后变为:0x0190F9D80C3F70890FB154F2123459506AD5BDA165333710D161ED80E42FCAFA882C66FF5B68E412B5F9EE11A9F308201D0AE2BD4032151308171FDBE2F3

关于 varchar(max) 的有趣之处在于,在插入数据的表旁边,可能存在指向表或存储数据的其他地方的链接,因此 varchar(max) 可能只占用显示的数量。(我是开发人员)

我的列和存储过程变量的数据类型: [testVarChar] varchar COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,

针对 SSN 列的参数的数据类型设置为 ANSI(非 Unicode)字符串,该字符串映射到 char/varchar SQL Server 数据类型。如果参数的类型设置为映射到 nchar/nvarchar 的 Unicode 字符串 (String),则查询将失败,因为 Always Encrypted 不支持从加密的 nchar/nvarchar 值到加密的 char/varchar 值的转换。有关数据类型映射的信息,请参阅 SQL Server 数据类型映射。

https://docs.microsoft.com/en-us/sql/relational-databases/security/encryption/develop-using-always-encrypted-with-net-framework-data-provider

于 2017-04-12T16:03:25.867 回答