这可以通过使用SQL Server加密基础结构来实现。使用自己的对称密钥加密每个对象(A,B,C,D)(数据始终使用对称密钥加密,从不使用对称密钥加密)。每个角色都有非对称密钥或证书,因此存在非对称密钥A,B和C.角色非对称密钥(s)使用角色的密码加密。每个对称密钥都由具有访问权限的角色的非对称密钥加密(对称密钥可以多次加密)。当用户进入系统时,它使用特定于角色的证书/不对称密钥来打开其角色的对称密钥。这将对称密钥放置在当前用户的钥匙串中,以访问用这些密钥加密的对象。
下面是一个代码演示:
:setvar server .
:setvar dbname cryptdemo
:connect $(server)
use master;
if db_id('$(dbname)') is not null
drop database [$(dbname)];
create database [$(dbname)];
go
:connect $(server)
use [$(dbname)];
go
create certificate RoleA
encryption by password = '123!#Password'
with subject = 'RoleA'
create certificate RoleB
encryption by password = '213!#Password'
with subject = 'RoleB'
create certificate RoleC
encryption by password = '312!#Password'
with subject = 'RoleC'
go
:connect $(server)
use [$(dbname)];
go
-- Role A has access to Object A and Object B
create symmetric key ObjectA WITH ALGORITHM = AES_256
encryption by certificate RoleA;
create symmetric key ObjectB WITH ALGORITHM = AES_256
encryption by certificate RoleA;
go
:connect $(server)
use [$(dbname)];
go
-- Role B has access to Object C
create symmetric key ObjectC WITH ALGORITHM = AES_256
encryption by certificate Roleb;
go
:connect $(server)
use [$(dbname)];
go
-- Role C has access to Objects A, B and C
open symmetric key ObjectA
decryption by certificate RoleA with password = '123!#Password'
alter symmetric key ObjectA
add encryption by certificate RoleC;
open symmetric key ObjectB
decryption by certificate RoleA with password = '123!#Password'
alter symmetric key ObjectB
add encryption by certificate RoleC;
open symmetric key ObjectC
decryption by certificate RoleB with password = '213!#Password'
alter symmetric key ObjectC
add encryption by certificate RoleC;
go
:connect $(server)
use [$(dbname)];
go
create table Objects (
id int not null identity(1,1) primary key,
data varbinary(max));
go
:connect $(server)
use [$(dbname)];
go
-- Role A inserts an Object A and an Object B:
open symmetric key ObjectA
decryption by certificate RoleA with password = '123!#Password'
open symmetric key ObjectB
decryption by certificate RoleA with password = '123!#Password'
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectA'), 'Object A inserted by Role A'));
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectB'), 'Object B inserted by Role A'));
go
:connect $(server)
use [$(dbname)];
go
-- Role B inserts an Object C
open symmetric key ObjectC
decryption by certificate RoleB with password = '213!#Password'
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectC'), 'Object C inserted by Role B'));
go
:connect $(server)
use [$(dbname)];
go
-- Role C inserts objects A, B, C
open symmetric key ObjectA
decryption by certificate RoleC with password = '312!#Password'
open symmetric key ObjectB
decryption by certificate RoleC with password = '312!#Password'
open symmetric key ObjectC
decryption by certificate RoleC with password = '312!#Password'
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectA'), 'Object A inserted by Role C'));
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectB'), 'Object B inserted by Role C'));
insert into Objects (data) values (encryptbykey(Key_GUID('ObjectC'), 'Object C inserted by Role C'));
go
:connect $(server)
use [$(dbname)];
go
-- Role A can see Objects A and B:
open symmetric key ObjectA
decryption by certificate RoleA with password = '123!#Password'
open symmetric key ObjectB
decryption by certificate RoleA with password = '123!#Password'
select id, data, cast(decryptbykey(data) as varchar(max)) as decrypted from Objects ;
go
:connect $(server)
use [$(dbname)];
go
-- Role B can see Object C
open symmetric key ObjectC
decryption by certificate RoleB with password = '213!#Password'
select id, data, cast(decryptbykey(data) as varchar(max)) as decrypted from Objects ;
go
:connect $(server)
use [$(dbname)];
go
-- Role C can see Objects A, B and C
open symmetric key ObjectA
decryption by certificate RoleC with password = '312!#Password'
open symmetric key ObjectB
decryption by certificate RoleC with password = '312!#Password'
open symmetric key ObjectC
decryption by certificate RoleC with password = '312!#Password'
select id, data, cast(decryptbykey(data) as varchar(max)) as decrypted from Objects ;
go
这是一个聪明的认为,虽然做?没有加密是从来没有解决访问权限问题的答案。你显然不理解密钥管理和配置,你会做一个毫无用处的伪安全混乱。不好意思在你的游行上下雨,但是有必要。