2010-05-16 39 views
3

我想弄清楚如何为我的项目创建最佳解决方案。我在Photoshop中制作了这个简单的图片,试图说明问题以及我想如何(如果可能)。如何构建允许多个用户/对象的加密系统

Illustrative image

生病也尝试根据画面来解释它。 首先我们在左边有几个对象,这些对象都用自己的加密密钥(图片上的EKey)进行加密,然后存储在数据库中。另一方面,我们将不同的用户放入角色中(一个用户可以扮演很多角色),角色与不同的对象相关联。所以一个人只能访问该角色提供的对象。因此,例如角色A可以访问对象A和B.角色B只能访问对象C,而角色C可以访问所有对象。 没有什么奇怪的,对吧?不同的角色拥有可以访问的不同对象。

现在问题部分。

每个用户都必须用他/她的用户名/密码登录,然后他/她才能访问他/她的角色提供的对象。所有对象都被加密,所以她需要以某种方式获得解密密钥。我不想将加密密钥作为文本字符串存储在服务器上。如果可能的话,应该使用用户密码(以及角色)或类似的密码进行解密。这样你必须成为服务器上的用户才能解密对象并使用它。

我在考虑制作一个公钥/私钥加密系统,但是我不知道如何给不同的用户提供解密密钥给对象。由于我需要能够将用户移入和移出角色,添加新用户,添加新角色以及创建/删除对象。

将会有一个管理员,然后添加一些数据,以允许该角色的用户获得解密密钥来解密对象。

没有什么是静态的,我想了解如何构建或如果有更好的解决方案。

唯一的标准是:

-加密的对象。

- 加密密钥不应该存储为文本。

- 不同的用户可以访问不同的对象。

- 不需要有角色。

回答

3

这可以通过使用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 

这是一个聪明的认为,虽然做?没有加密是从来没有解决访问权限问题的答案。你显然不理解密钥管理和配置,你会做一个毫无用处的伪安全混乱。不好意思在你的游行上下雨,但是有必要。

1

听起来好像你试图通过用不同的密钥加密每一类资源来实现访问限制,是正确的吗?

在描述它时,似乎没有一种很好的方法来实现该方案。考虑让资源通过一个密钥加密。您必须将解密密钥公开给用户,但如果其角色发生更改,则无法撤销访问权限,而无需使用新密钥重新加密对象,这可能会使其他用户密钥(不一定)失效。另一种方法是让每个用户拥有一个公钥,并且每个资源都将根据所有有权访问的用户的公钥进行加密。但对象必须重新加密才能添加或删除访问权限。如果角色更改很少,并且您不介意重新加密以强制执行访问限制,则您的方法才可行。

您可以考虑解耦存储加密和受保护的访问。数据库可以在total中加密,并且服务器可以在启动时提示输入密钥(不存储)。访问控制的类型取决于您的中间层的样子,这听起来像您的管理员可以通过添加和删除数据库权限来更改角色(您可以详细说明“登录”是什么类型的操作系统,数据库或自定义服务器软件登录? )。要将对象安全地传输到远程用户,请使用SSH隧道或SSL连接。在这种方法中,对象在光盘上进行加密,在传输过程中可以自由更改角色而无需重新加密。

相关问题