【问题标题】:Column Level encryption, select query in stored procedure with where clause is not working列级加密,在带有 where 子句的存储过程中选择查询不起作用
【发布时间】:2019-07-31 11:52:59
【问题描述】:

下面是table和insert的脚本

CREATE TABLE [dbo].[registration]
(
    [Email] [VARCHAR](MAX) NULL,
    [Name] [VARCHAR](MAX) NULL,
    [Address] [VARCHAR](MAX) NULL
) ON [PRIMARY]
GO

INSERT INTO registration 
VALUES ('sample1@test.com', 'Sample1', 'New Jersey'),
       ('sample2@test.com', 'Sample2', 'New York'),
       ('sample3@test.com', 'Sample3', 'Chicago');

通过创建始终加密密钥(列主密钥和列加密密钥),在电子邮件字段上启用列级加密。使用“启用始终加密”登录 SSMS

创建了这个存储过程:

CREATE PROCEDURE prod_getregistration
    @Email VARCHAR(MAX)
AS 
BEGIN
    SELECT * 
    FROM registration 
    WHERE Email = @Email
END

prod_getregistration 'sampletest@test.com'

执行程序时,我得到这个错误:

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

where 子句是否可以用于加密列?

【问题讨论】:

  • 我不得不问,你为什么使用varchar(MAX) 来存储姓名、地址和电子邮件之类的东西?我怀疑世界上是否有人名字中有 2147483648 个字符。
  • 所有字段都已加密,我想确保大小不会导致此错误,这就是我给出 varchar(max) 的原因,无论如何,谢谢。

标签: sql-server encryption


【解决方案1】:

为了简单地回答您的问题,是的,可以在使用 Always Encrypted 的加密列上使用 where 子句。

话虽如此,您在这里面临的问题是由于服务器如何执行该过程。要了解这里发生了什么,我们需要知道表中的列在加密后是如何变化的。在加密过程之前,该列将数据存储为纯文本

经过加密后,​​数据将转换为二进制数据。您可以通过在启用和不启用始终加密功能的情况下连接到数据库并查询表来查看这方面的证据。现在您可以在加密的电子邮件列中看到二进制数据的十六进制表示。

按照上面定义的执行过程,服务器正在尝试将纯文本电子邮件与加密的密文值进行比较,这会导致您看到类型冲突。

using parameterization在调用过程时,会将查询参数加密后发送到服务器,以便将查询密文值与数据库密文值进行比较。您对存储过程的调用的以下更改应该适合您。

DECLARE @value VARCHAR(MAX) = 'sample2@test.com'
EXEC prod_getregistration @value

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 2011-07-05
    • 1970-01-01
    • 2022-06-17
    • 2019-08-27
    • 1970-01-01
    相关资源
    最近更新 更多