Как построить эту систему шифрования, которая позволяет нескольким пользователям / объектам - PullRequest
3 голосов
/ 16 мая 2010

Я пытаюсь понять, как создать оптимальное решение для моего проекта. Я сделал эту простую картинку в Photoshop, чтобы попытаться проиллюстрировать проблему и то, как я хочу ее (если это возможно).

Иллюстративное изображение

Я также попытаюсь объяснить это на основе рисунка. Прежде всего, у нас есть пара объектов слева, все эти объекты шифруются с помощью собственного ключа шифрования (EKey на рисунке), а затем сохраняются в базе данных. С другой стороны, у нас есть разные пользователи, помещенные в роли (у одного пользователя может быть много ролей), и роли связаны с разными объектами. Таким образом, один человек имеет доступ только к объектам, которые предоставляет роль. Так, например, роль A может иметь доступ к объектам A и B. Роль B имеет доступ только к объекту C, а роль C имеет доступ ко всем объектам. Ничего странного в этом нет? У разных ролей есть разные объекты, к которым они могут получить доступ.

Теперь к проблемной части.

Каждый пользователь должен войти в систему со своим именем пользователя / паролем, а затем он / она получает доступ к объектам, которые предоставляют его / ее роли. Все объекты зашифрованы, поэтому ей нужно как-то получить ключ расшифровки. Я не хочу хранить ключ шифрования в виде текстовой строки на сервере. Он должен быть, если возможно, расшифрован с использованием пароля пользователя (вместе с ролью) или аналогичным. Таким образом, вы должны быть пользователем на сервере, чтобы расшифровать объект и работать с ним.

Я думал о создании системы шифрования с открытым / закрытым ключом, но я как бы застрял в том, как дать различным пользователям ключ дешифрования для объектов. Поскольку мне нужно иметь возможность перемещать пользователей в роли и из ролей, добавлять новых пользователей, добавлять новые роли и создавать / удалять объекты.

Будет один администратор, который затем добавит некоторые данные, чтобы позволить пользователям в этой роли получить ключ дешифрования для дешифрования объекта.

Ничто не является статичным, и я пытаюсь получить представление о том, как это можно построить, или если есть гораздо лучшее решение.

Единственными критериями являются:

- зашифрованные объекты.

-Декодер не должен храниться в виде текста.

- Разные пользователи имеют доступ к различным объектам.

-Не нужно иметь роли.

Ответы [ 2 ]

3 голосов
/ 16 мая 2010

Это возможно при использовании криптографической инфраструктуры SQL Server. Вы шифруете каждый объект (A, B, C, D) своим собственным симметричным ключом (данные всегда шифруются симметричным ключом, а не асимметричным). Каждая роль имеет асимметричный ключ или сертификат, поэтому существуют асимметричные ключи A, B и C. Роли асимметричного ключа (ключей) зашифрованы паролем роли. Каждый симметричный ключ шифруется асимметричными ключами ролей, которые имеют к нему доступ (симметричные ключи могут быть зашифрованы несколько раз). Когда пользователь входит в систему, он открывает симметричный ключ (ключи) своей роли, используя сертификат / ассиметричный ключ для конкретной роли. Это помещает симметричные ключи в цепочку ключей текущего пользователя, предоставляя доступ к объектам, зашифрованным этими ключами.

Вот пример кода:

: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 голос
/ 16 мая 2010

Похоже, вы пытаетесь ввести ограничения доступа с помощью шифрования каждого класса ресурсов с другим ключом, верно?

Кажется, нет хорошего способа реализовать схему, как вы ее описали. Рассмотрите возможность шифрования ресурсов одним ключом. Вам обязательно нужно будет предоставить ключ дешифрования пользователям, но если их роли изменятся, то нет способа отозвать доступ без повторного шифрования объектов новым ключом, что может сделать недействительными ключи других пользователей (не обязательно). Другой подход заключается в том, чтобы каждый пользователь имел открытый ключ, и каждый ресурс был бы зашифрован с использованием открытых ключей всех пользователей, имеющих доступ. Но объекты должны быть повторно зашифрованы, чтобы добавить или удалить доступ. Ваш подход оправдан только в том случае, если смена ролей происходит редко, и вы не возражаете против повторного шифрования для ограничения доступа.

Вы можете рассмотреть возможность разделения шифрования и защищенного доступа к хранилищу. База данных может быть зашифрована в всего , и сервер может запросить ключ при запуске (без хранения). Тип управления доступом зависит от того, как выглядит ваш средний уровень. Похоже, ваш администратор мог бы менять роли, добавляя и удаляя привилегии базы данных (не могли бы вы уточнить, какой тип компонента «Логин»? ). Для безопасной передачи объектов удаленным пользователям используйте туннель SSH или соединение SSL. При таком подходе объекты шифруются на диске и во время передачи, и роли можно свободно менять без повторного шифрования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...