【问题标题】:SQL Server always encrypted with Dynamic SQLSQL Server 始终使用动态 SQL 加密
【发布时间】:2018-03-11 18:06:51
【问题描述】:

我正在使用 SQL Server 始终对 SSN 列的功能进行加密。我创建了一个存储过程并从 .net 代码中调用它。我在我的连接字符串中使用列加密设置=true。从 .net 代码调用动态存储过程会抛出这个错误:

操作数类型冲突:varchar 与使用 (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'ColumnKey', column_encryption_key_database_name = 'DatabaseName') 加密的 varchar(4) 不兼容 collat​​ion_name = 'SQL_Latin1_General_CP1_CI_AS' >

有人可以提供一个示例代码,该代码可以通过使用参数化搜索加密列来检索数据吗?

CREATE PROCEDURE [dbo].[testSSN_Dynamic]
    @Last4SSN VARCHAR(50) 
AS
BEGIN
    DECLARE @query NVARCHAR(4000);

    SET @query = 'Select [SSNumber], [last4SSNumber] from table_XXX   WHERE last4SSNumber =  @Last4SSN ;'

    EXEC sp_executesql @query, N'@Last4SSN varchar(4)', @Last4SSN ;
END

在应用程序中,SSN 号码使用随机加密进行加密。 Last4SSNumber 使用确定性加密进行加密。搜索基于 SSN 号码的最后 4 位,过滤后的列表将仅获得最后 4 位匹配的 SSN 号码,其余所有数字在应用程序中被屏蔽。由于加密随机和确定性不支持类似操作,因此添加了 last4SSNumber 列。

当我从 .NET 代码中调用没有动态 SQL 的上述存储过程时,它可以正常工作,并且我能够检索匹配 SSN 的最后 4 位数字的列表..

在应用程序中有现有的存储过程,其中传递了很多参数。搜索条件基于值是否传递给参数。 Last4SSNumber 是传递的参数之一。我提供了一个简单的存储过程示例,而不是包含所有参数的整个存储过程。根据传递给参数的值构建搜索条件。

在各种帖子中已经指出,动态 SQL 必须转换为参数化查询才能使用始终加密的功能。我对上述存储过程应用了参数化,但在从 .NET 代码调用存储过程时仍然收到错误消息。

【问题讨论】:

  • 如果您使用“确定性”加密,(相同的值始终以相同的方式加密),您可以加密参数值并以这种方式进行搜索。如果您使用随机加密,那么您就是 SOL... 请参阅 MS 文档的“选择确定性或随机加密”部分...docs.microsoft.com/en-us/sql/relational-databases/security/…

标签: encryption dynamic-sql sql-server-2016 always-encrypted sql-parametrized-query


【解决方案1】:

目前不支持将动态 SQL 与针对加密列进行评估的参数一起使用。

不幸的是,Always Encrypted 不支持以以下方式执行查询

EXEC sp_executesql @query, N'@Last4SSN varchar(4)', @Last4SSN ;

但是,如果您能够以下列方式重构您的存储过程,您可能会有一个可行的解决方案。

CREATE PROCEDURE [dbo].[testSSN]
    @Last4SSN VARCHAR(50) 
AS
BEGIN    
    Select [SSNumber], [last4SSNumber] from table_XXX   WHERE last4SSNumber =  @Last4SSN ;
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多