¿Cómo implementar el control de acceso basado en roles a los datos privados del usuario?

Tenemos este escenario de aplicación e intentamos ver si Ethereum, o blockchain en general, es una buena solución para esto.

La idea básica es que el usuario controla una pequeña cantidad de datos confidenciales privados (p. ej., historial de cambios de perfil individual, historial de transacciones). El usuario puede controlar quién tiene acceso a esos datos. Cuando el usuario A activa el acceso para otro usuario B, B puede ver todo el historial de transacciones. Obviamente, otros usuarios sin acceso no deberían ver los datos de A.

Estamos pensando en almacenar los datos cifrados del usuario en la cadena de bloques pública. Ethereum es una de las opciones que estamos considerando. Las ventajas de hacerlo es:

  • Tiempo de inactividad descentralizado o cero

  • Cualquier usuario con acceso ve el rastro de transacción inalterable (bueno para fines de auditoría)

Preguntas :

  • ¿Cómo implementaría el control de acceso basado en roles a la clave de cifrado de contenido ?

Obviamente, no podemos cifrar el contenido con la clave privada del usuario, de lo contrario, cuando el usuario quiera compartir datos, tendrá que dar la clave privada para descifrar el contenido.

Por lo tanto, cada unidad de datos privados debe tener una clave de cifrado única. Y tenemos que cambiar la clave de cifrado y volver a cifrar el contenido cada vez que el usuario revoca el acceso de otra persona.

Entonces eso lleva a otra pregunta:

  • ¿Dónde debemos almacenar estas claves de cifrado ?

¿Deberíamos almacenarlos en una base de datos de propiedad privada? Una pregunta más general es, dado que blockchain logra rastrear la propiedad en un libro público compartido, ¿puede implementar un control de acceso basado en roles completamente con todo (excepto las claves privadas del usuario) en la cadena pública también?

ACTUALIZACIONES

Gracias por la respuesta de Rob Hitchens. Leí la publicación del blog de Vitalik y descubrí que es difícil implementar computación ofuscada en cadena. Por lo tanto, es imposible almacenar todo en la cadena pública mientras se mantiene la privacidad de los datos del usuario.

Eso exige que necesitemos algún tipo de almacenamiento privado para lograr la privacidad. Una idea es usar la cadena pública solo para el mantenimiento de registros de permisos. por ejemplo, declaramos

mapping (address => bool) permissions;

Y solo senderpuede asignar establecer el permiso de cualquier cuenta a verdadero o falso. Nuestro servidor de autenticación privado respeta esta asignación de permisos (almacenada en cadena pública) y solo permite que un usuario autenticado (es decir, el usuario que posee la clave privada de una cuenta autorizada) acceda a la clave de cifrado de contenido.

Si usamos el diseño anterior, para autenticarse, el propietario de la cuenta debe usar la clave privada para calcular una firma, y ​​el servidor de autenticación debe verificar eso. Eso parece similar a la forma en que se verifica la identidad en las transacciones de ethereum.

¿Funcionará el enfoque anterior? o más importante, ¿hay un mejor diseño?

Respuestas (2)

De acuerdo con Sanchit sobre el uso de modificadores para controlar el acceso a las funciones.

Sin embargo, la implementación del ejemplo es engañosa. Marcaría eso para un rediseño.

Un par de cosas a considerar.

En lo que respecta al almacenamiento de datos, es posible que desee considerar la serialización fuera de la cadena con cifrado. Esto, para reducir el costo total de almacenamiento sin comprometer la naturaleza distribuida de la aplicación.

Por privacidad, veo que sabe que la información en Ethereum es visible para todas las partes. Considere usar el cifrado de múltiples partes con un contrato inteligente para ayudar a distribuir el "secreto" a varias partes autorizadas.

Para la escalabilidad, el modificador de @Sanchit debe eliminar el forciclo ilimitado. En pocas palabras, for(i=0;i<n;i++) es un anti-patrón . En cierto modo n, el costo de ejecución excederá el límite de gas del bloque, lo que significa que fallará en todos los casos. En otras palabras, implementado de esa manera garantiza que una aplicación exitosa eventualmente fallará, posiblemente de una manera que no pueda repararse.

Lo que se muestra es perfectamente lógico en un mundo centrado en el servidor. En Ethereum, todas las funciones necesitan un costo de gas (aproximadamente) fijo en cualquier escala. Una solución es refactorizar con búsquedas de 1 paso usando mapping.

Solo menciono esto porque este error existe en muchos contratos y espero que la respuesta (en general estoy de acuerdo) no lleve a los codificadores a replicar ese tipo de defecto.

Espero eso ayude.

Gracias por la respuesta. Leí la publicación del blog de Vitalik ( blog.ethereum.org/2016/01/15/privacy-on-the-blockchain ) y descubrí que es difícil implementar la computación ofuscada en cadena. Por lo tanto, es imposible almacenar todo en la cadena pública mientras se mantiene la privacidad de los datos del usuario. ¿Estoy interpretando eso bien?
Supongo que para proteger la privacidad tenemos que confiar en un almacenamiento de datos privado y usar la cadena pública solo para el mantenimiento de registros de permisos. El servidor de autenticación respeta la matriz de permisos (almacenada en la cadena pública) y solo permite que un usuario autenticado (es decir, el usuario que posee la clave privada de una cuenta autorizada) acceda a la clave de cifrado.
Gracias @Rob por señalar problemas, refactorizaré mi código y actualizaré la respuesta.
@ user10375 Solo reformulando en caso de que ayude. El contrato puede garantizar que una función solo se ejecute si el firmante está en una lista de control de acceso, o incluso si un hash de la dirección del firmante está en una ACL (más privado), pero no puede impedir que una parte interesada explore los datos. . Es inútil dado que todos los mineros/verificadores deben ver los datos para trabajar (en este momento). No necesitan el permiso de una función para realizar una exploración de solo lectura.
@RobHitchens Para evitar que los mineros lean los datos privados, parece que la mejor solución es sacar los datos de la cadena. Alternativamente, podemos cargar los datos encriptados, pero eso causaría demasiada quema de computación y almacenamiento para los nodos de ehtereum. ¿Aceptar?
@ usuario10375 De acuerdo.

Puede implementar el control de acceso en sus funciones de contrato inteligente con la ayuda de modificadores. Digamos que no desea que todos los usuarios de su contrato llamen a alguna función, en ese caso, puede crear un modificador y restringir el uso de la función. De manera similar, puede tener múltiples modificadores para diferentes roles según su caso.

Un modificador de muestra, que estoy usando en uno de mis proyectos: "Solo miembro"

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);
    }

Espero que esto ayude.

Gracias. Esto definitivamente ayuda y resuelve la pregunta de implementación del control de acceso basado en roles. Mi siguiente pregunta es ¿qué debería hacer esa función de contrato inteligente? ¿Puede una función de contrato inteligente desencadenar algo fuera de la cadena?
La función de contrato inteligente contendría su definición de lógica comercial, cualquier funcionalidad que desee tener dentro. Como en mi ejemplo, obtengo la lista de libros asociados con el propietario usando otra función llamada getBooks(). Además, creo que sí, la función de contrato inteligente también puede desencadenar algo fuera de la cadena. No he probado esto, pero deberías echarle un vistazo a oraclize.it