如何拒绝访问 SQL 服务器中的对称密钥别名?

How do I deny access to a symmetric key alias in SQL Server?

我有一个 table 和一些加密数据:

select * from Test1;

这会产生一些包含我创建的垃圾数据的行...两行,都有名称和密文,由以下命令创建,发出两次,略有不同:

insert into Test1 values
('travis', ENCRYPTBYKEY(key_guid('aes128'), convert(varchar, 1234567)));

密钥是在 EKM 设备上创建的,在 SQL 中的别名如下:

create symmetric key aes128 from provider EKMProvider with provider_key_name = 'aes128', creation_disposition = open_existing;

我有两个用户:一个用户 (administrator) 我希望拥有对 SQL 服务器授予的完全权限的无限制访问权限,第二个用户 (restrictedsql)我想拒绝访问此加密密钥。

现在,如果我尝试将此密钥用作 restrictedsql,我可以 DECRYPT 但我不能 ENCRYPT:

select ENCRYPTBYKEY(key_guid('aes128'), 'Hello World');

产量 NULL.

然而,

 select name, CONVERT(varchar, DECRYPTBYKEY(number)) from Test1;

产生所有明文数据。我认为加密功能在解密时不起作用的原因与授予的 ddladmin 权限有关,这很奇怪但有点离题:我想要的结果是这个用户应该没有访问这个密钥的权限,并且任何尝试解密或加密应该会失败。用户应该保留对列和密文的访问权限,只是不能查看明文或插入正确加密的数据。

我发出了以下命令:

DENY View Definition ON SYMMETRIC KEY::aes128 TO restrictedsql;
DENY Control ON SYMMETRIC KEY::aes128 TO restrictedsql;

他们成功了,但没有产生任何不同的结果。

请注意,密钥是由 EKM 提供的,因此无法通过将密钥包装在 UAC 中来保护密钥 certificate/key。我需要直接 UAC 对称密钥别名。


更新:我有两个脚本演示了本机 SQL 服务器 AES 密钥和 EKM 提供的 SQL 服务器 AES 密钥之间权限语句行为的差异。请注意,这假定 EKM 提供程序已经创建并且密钥是在 EKM 提供程序上创建的。

第一个脚本由具有完全访问权限的管理用户执行:

create table Test2 (
name varchar(25),
ekm128_enc varbinary(256),
local128_enc varbinary(256),
);

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sql$server123';

CREATE CERTIFICATE localcert
WITH SUBJECT = 'TestSqlServer';

CREATE SYMMETRIC KEY local128 
WITH ALGORITHM = AES_128
ENCRYPTION BY CERTIFICATE localcert;

CREATE SYMMETRIC KEY ekm128 
FROM PROVIDER EKMProvider 
WITH provider_key_name = 'ekm128', 
creation_disposition = open_existing;

OPEN SYMMETRIC KEY local128 DECRYPTION BY CERTIFICATE localcert;

insert into Test2 values ('travisthomas', ENCRYPTBYKEY(key_guid('ekm128'), 'travisthomas_ekm'), ENCRYPTBYKEY(key_guid('local128'), 'travisthomas_local'));


select name, ekm128_enc, convert(varchar, DECRYPTBYKEY(ekm128_enc)) as ekm128_dec, local128_enc, CONVERT(varchar, DECRYPTBYKEY(local128_enc)) as local128_dec from Test2;
/* execute through this point... the select statement should work flawlessly... the ciphertext and the plaintext should all be visible and not-null */

/* execute after this point next to set the permissions on both ekm128 and local128 */
DENY View Definition ON SYMMETRIC KEY::ekm128 TO restrictedsql;
DENY Control ON SYMMETRIC KEY::ekm128 TO restrictedsql;
DENY View Definition ON SYMMETRIC KEY::local128 TO restrictedsql;
DENY Control ON SYMMETRIC KEY::local128 TO restrictedsql;

select name, ekm128_enc, convert(varchar, DECRYPTBYKEY(ekm128_enc)) as ekm128_dec, local128_enc, CONVERT(varchar, DECRYPTBYKEY(local128_enc)) as local128_dec from Test2;
/* This select statement should provide identical output as the select statement above the "DENY"s */

第二个脚本应该由受限用户执行,在本例中为 restrictedsql。

OPEN SYMMETRIC KEY local128 DECRYPTION BY CERTIFICATE localcert;
/* this statement fails due to lack of permissions */

select name, ENCRYPTBYKEY(key_guid('ekm128'), 'test') as ekm128_encrypt, CONVERT(varchar, decryptbykey(ekm128_enc)) as ekm128_dec, ENCRYPTBYKEY(key_guid('local128'), 'test') as local128_encrypt, CONVERT(varchar, decryptbykey(local128_enc)) as local128_dec from Test2;
/* null for all except EKM decryption! permissions don't apply! */

我从微软收到的答复:在这​​种架构中这是不可能的。密钥标识符绑定在密文中并由 EKM 提供程序解释,而不是 SQL 服务器。 SQL 服务器甚至不知道正在使用哪个密钥。由 EKM 提供商提供 UAC。