列级加密,使用where子句不起作用的存储过程中选择查询

时间:2019-03-09 17:55:22

标签: sql-server encryption

下面是用于表和插入的脚本

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_lation_AS _'___ base_atin_1'的__char__base_en_ion_l_base_en__base_p___base >

在加密列上可以使用where子句吗?

1 个答案:

答案 0 :(得分:1)

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

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

enter image description here

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

Query without Always Encrypted Enabled

通过执行上述定义的过程,服务器正在尝试将纯文本电子邮件与加密的密文值进行比较,从而使您看到类型冲突。

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

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

enter image description here