Как реализовать ролевое управление доступом к личным данным пользователя?

У нас есть этот сценарий приложения, и мы пытаемся понять, является ли Ethereum или блокчейн в целом хорошим решением для этого.

Основная идея заключается в том, что пользователь контролирует небольшой объем личных конфиденциальных данных (например, историю изменений индивидуального профиля, историю транзакций). Пользователь может контролировать, кто имеет доступ к этим данным. Когда пользователь A включает доступ для другого пользователя B, B может видеть всю историю транзакций. Очевидно, что другие пользователи без доступа не должны видеть данные А.

Мы думаем о хранении зашифрованных данных пользователя в общедоступной цепочке блоков. Ethereum — один из рассматриваемых нами вариантов. Преимущества этого:

  • Децентрализованность или нулевое время простоя

  • Любой пользователь с доступом видит неизменяемый след транзакции (хорошо для целей аудита)

Вопросы :

  • Как бы вы реализовали управление доступом на основе ролей к ключу шифрования контента ?

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

Таким образом, каждая единица личных данных должна иметь уникальный ключ шифрования. И нам приходится менять ключ шифрования и повторно шифровать контент каждый раз, когда пользователь отменяет чей-то доступ.

Так что это приводит к другому вопросу:

  • Где мы должны хранить эти ключи шифрования ?

Должны ли мы хранить их в частной базе данных? Более общий вопрос заключается в том, что, поскольку блокчейн обеспечивает отслеживание прав собственности в общедоступной общей книге, может ли он полностью реализовать ролевой контроль доступа ко всему (кроме закрытых ключей пользователя) в общедоступной цепочке?

ОБНОВЛЕНИЯ

Спасибо за ответ Роба Хитченса. Я прочитал запись в блоге Виталика и обнаружил, что сложно реализовать запутанные вычисления в цепочке. Таким образом, невозможно хранить все в общедоступной сети, сохраняя при этом конфиденциальность данных пользователя.

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

mapping (address => bool) permissions;

И только senderможет назначить разрешение любой учетной записи на true или false. Наш частный сервер аутентификации учитывает это сопоставление разрешений (хранящееся в общедоступной цепочке) и разрешает только аутентифицированному пользователю (т. е. пользователю, которому принадлежит закрытый ключ авторизованной учетной записи) доступ к ключу шифрования контента.

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

Будет ли работать описанный выше подход? или, что более важно, есть ли лучший дизайн?

Ответы (2)

Согласитесь с Санчитом об использовании модификаторов для управления доступом к функциям.

Однако пример реализации вводит в заблуждение. Я бы отметил это для редизайна.

Несколько вещей, чтобы рассмотреть.

Что касается хранилища данных, вы можете рассмотреть возможность сериализации вне цепочки с шифрованием. Это позволяет снизить общую стоимость хранения без ущерба для распределенного характера приложения.

Что касается конфиденциальности, я вижу, вы знаете, что информация в Ethereum видна всем сторонам. Рассмотрите возможность использования многостороннего шифрования со смарт-контрактом, чтобы помочь распределить «секрет» нескольким авторизованным сторонам.

Для масштабируемости модификатор @Sanchit должен устранять неограниченный forцикл. Проще говоря, for(i=0;i<n;i++) это анти-шаблон . В какой -то nмомент стоимость выполнения превысит блок gasLimit, что означает отказ во всех случаях. Другими словами, реализация таким образом гарантирует, что успешное приложение в конечном итоге выйдет из строя, возможно, таким образом, что его нельзя будет исправить.

То, что показано, совершенно логично в мире, ориентированном на серверы. В Ethereum для всех функций требуется (приблизительно) фиксированная стоимость газа в любом масштабе. Решением является рефакторинг с одноэтапным поиском с использованием mapping.

Просто упомянул об этом, потому что эта ошибка существует во многих контрактах, и я надеюсь, что ответ (я в целом согласен) не приведет к тому, что кодеры воспроизведут такой дефект.

Надеюсь, поможет.

Спасибо за ответ. Я прочитал сообщение в блоге Виталика ( blog.ethereum.org/2016/01/15/privacy-on-the-blockchain ) и обнаружил, что реализовать запутанные вычисления в цепочке сложно. Таким образом, невозможно хранить все в общедоступной сети, сохраняя при этом конфиденциальность данных пользователя. Я правильно интерпретирую?
Я предполагаю, что для защиты конфиденциальности мы должны полагаться на частное хранилище данных и использовать общедоступную цепочку только для ведения учета разрешений. Сервер аутентификации учитывает матрицу разрешений (хранящуюся в общедоступной цепочке) и разрешает доступ к ключу шифрования только аутентифицированному пользователю (то есть пользователю, которому принадлежит закрытый ключ авторизованной учетной записи).
Спасибо @Rob за указание на проблемы, я проведу рефакторинг своего кода и обновлю ответ.
@user10375 user10375 Просто перефразирую, вдруг поможет. Контракт может гарантировать выполнение функции только в том случае, если подписывающая сторона находится в списке управления доступом или даже если хэш адреса подписывающей стороны находится в ACL (более конфиденциальном), но он не может помешать заинтересованной стороне изучить данные. . Это бесполезно, учитывая, что все майнеры/верификаторы должны видеть данные для работы (в настоящее время). Им не нужно разрешение от функции для исследования только для чтения.
@RobHitchens Кажется, что лучшим решением для предотвращения чтения майнерами личных данных является удаление данных из цепочки. В качестве альтернативы мы можем загрузить зашифрованные данные, но это приведет к слишком большому объему вычислений и памяти для узлов Эфириума. Соглашаться?
@ user10375 Согласен.

Вы можете реализовать контроль доступа к своим функциям смарт-контракта с помощью модификаторов. Допустим, вы не хотите, чтобы какая-то функция вызывалась всеми, кто использует ваш контракт, в этом случае вы можете создать модификатор и ограничить использование функции. Аналогичным образом вы можете иметь несколько модификаторов для разных ролей в соответствии с вашим случаем.

Пример модификатора, который я использую в одном из своих проектов - "Only Member"

modifier onlyMember {
    var index = DataStore(memberStore).getAddressIndex('account', msg.sender);
    var state = DataStore(memberStore).getIntValue(index, 'state');
    if (index != 0 && state == 0) {
        _;
    } else {
        Status(100);
    }
}

//modifier usage    
    function getMyBooks() constant onlyMember returns (string bookString, uint8 count) {
        return getBooks(true);
    }

Надеюсь это поможет.

Спасибо. Это определенно помогает и решает вопрос реализации управления доступом на основе ролей. Мой следующий вопрос: что должна делать эта функция смарт-контракта? Может ли функция смарт-контракта каким-то образом запускать что-то вне сети?
Функция смарт-контракта будет содержать определение вашей бизнес-логики, независимо от того, какую функциональность вы хотите иметь внутри нее. Как и в моем примере, я получаю список книг, связанных с владельцем, используя другую функцию, называемую getBooks(). Кроме того, я думаю, что да, функция смарт-контракта может запускать что-то вне сети. Я не пробовал это, но вы должны взглянуть на oraclize.it